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()),
nullptr);
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 ";
876 if (R__t) finalString <<
" " << tiName <<
" " << R__t <<
";" << std::endl;
879 case kBIT_ISFUNDAMENTAL:
881 finalString <<
" R__b >> " << R__t <<
";" << std::endl;
884 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
886 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
895 finalString <<
" Int_t readtemp;" << std::endl
896 <<
" R__b >> readtemp;" << std::endl
897 <<
" " << R__t <<
" = static_cast<" << tiName <<
">(readtemp);" << std::endl;
900 case kBIT_HASSTREAMER:
901 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
903 finalString <<
" " << R__t <<
".Streamer(R__b);" << std::endl;
906 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
909 finalString <<
" if (R__b.GetInfo() && R__b.GetInfo()->GetOldVersion()<=3) {" << std::endl;
910 if (cxxtype && cxxtype->isAbstract()) {
911 finalString <<
" R__ASSERT(0);// " << objType <<
" is abstract. We assume that older file could not be produced using this streaming method." << std::endl;
913 finalString <<
" " << R__t <<
" = new " << objType <<
";" << std::endl
914 <<
" " << R__t <<
"->Streamer(R__b);" << std::endl;
916 finalString <<
" } else {" << std::endl
917 <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl
918 <<
" }" << std::endl;
923 finalString <<
" {TString R__str;" << std::endl
924 <<
" R__str.Streamer(R__b);" << std::endl
925 <<
" " << R__t <<
" = R__str.Data();}" << std::endl;
928 case kBIT_ISSTRING|kBIT_ISPOINTER:
930 finalString <<
" {TString R__str;" << std::endl
931 <<
" R__str.Streamer(R__b);" << std::endl
932 <<
" " << R__t <<
" = new string(R__str.Data());}" << std::endl;
937 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
942 finalString <<
" R__b.StreamObject(&" << R__t <<
"," << tcl <<
");" << std::endl;
950 case kBIT_ISFUNDAMENTAL:
951 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
953 finalString <<
" R__b << " << R__t <<
";" << std::endl;
958 finalString <<
" { void *ptr_enum = (void*)&" << R__t <<
";\n";
959 finalString <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_enum); }" << std::endl;
962 case kBIT_HASSTREAMER:
963 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
965 finalString <<
" ((" << objType <<
"&)" << R__t <<
").Streamer(R__b);" << std::endl;
968 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
970 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
975 finalString <<
" {TString R__str(" << R__t <<
".c_str());" << std::endl
976 <<
" R__str.Streamer(R__b);};" << std::endl;
979 case kBIT_ISSTRING|kBIT_ISPOINTER:
981 finalString <<
" {TString R__str(" << R__t <<
"->c_str());" << std::endl
982 <<
" R__str.Streamer(R__b);}" << std::endl;
987 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
992 finalString <<
" R__b.StreamObject((" << objType <<
"*)&" << R__t <<
"," << tcl <<
");" << std::endl;
1004 clang::CXXRecordDecl* ncCl =
const_cast<clang::CXXRecordDecl*
>(cl);
1007 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
1009 if (
auto* Ctor = interpreter.getCI()->getSema().LookupDefaultConstructor(ncCl)) {
1010 if (Ctor->getAccess() == clang::AS_public && !Ctor->isDeleted()) {
1023 const char *typeOfArg,
1024 const clang::CXXRecordDecl *expectedArgType,
1025 const cling::Interpreter& interpreter)
1027 if (typeOfArg && !expectedArgType) {
1028 const cling::LookupHelper& lh = interpreter.getLookupHelper();
1031 clang::QualType instanceType = lh.findType(typeOfArg, cling::LookupHelper::WithDiagnostics);
1032 if (!instanceType.isNull())
1033 expectedArgType = instanceType->getAsCXXRecordDecl();
1036 if (!expectedArgType)
1037 return EIOCtorCategory::kAbsent;
1040 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
1041 for (
auto iter = cl->ctor_begin(), end = cl->ctor_end(); iter != end; ++iter)
1043 if ((iter->getAccess() != clang::AS_public) || (iter->getNumParams() != 1))
1047 clang::QualType argType((*iter->param_begin())->getType());
1048 argType = argType.getDesugaredType(cl->getASTContext());
1050 auto ioCtorCategory = EIOCtorCategory::kAbsent;
1051 if (argType->isPointerType()) {
1052 ioCtorCategory = EIOCtorCategory::kIOPtrType;
1053 argType = argType->getPointeeType();
1054 }
else if (argType->isReferenceType()) {
1055 ioCtorCategory = EIOCtorCategory::kIORefType;
1056 argType = argType.getNonReferenceType();
1060 argType = argType.getDesugaredType(cl->getASTContext());
1061 const clang::CXXRecordDecl *argDecl = argType->getAsCXXRecordDecl();
1063 if (argDecl->getCanonicalDecl() == expectedArgType->getCanonicalDecl()) {
1064 return ioCtorCategory;
1067 std::string realArg = argType.getAsString();
1068 std::string clarg(
"class ");
1070 if (realArg == clarg)
1071 return ioCtorCategory;
1075 return EIOCtorCategory::kAbsent;
1084 const cling::Interpreter& interpreter)
1086 const char *arg = ioctortype.
GetName();
1088 if (!ioctortype.
GetType() && (!arg || !arg[0])) {
1101 const char *method,
const char *
proto,
1102 const cling::Interpreter &interp,
1105 const clang::FunctionDecl* funcD
1106 = interp.getLookupHelper().findFunctionProto(cinfo, method,
proto,
1107 diagnose ? cling::LookupHelper::WithDiagnostics
1108 : cling::LookupHelper::NoDiagnostics);
1110 return llvm::dyn_cast<const clang::CXXMethodDecl>(funcD);
1119 namespace TMetaUtils {
1122 const cling::LookupHelper& lh = interp.getLookupHelper();
1125 clang::QualType instanceType = lh.findType(type_of_arg, cling::LookupHelper::WithDiagnostics);
1126 if (!instanceType.isNull())
1127 fArgType = instanceType->getAsCXXRecordDecl();
1141 const cling::Interpreter &interp)
1143 if (cl->isAbstract())
return false;
1145 for (
auto & ctorType : ctorTypes) {
1149 if (EIOCtorCategory::kAbsent == ioCtorCat)
1152 std::string
proto( ctorType.GetName() );
1153 bool defaultCtor =
proto.empty();
1159 if (EIOCtorCategory::kIOPtrType == ioCtorCat) {
1161 }
else if (EIOCtorCategory::kIORefType == ioCtorCat) {
1165 arg +=
")nullptr )";
1168 const clang::CXXMethodDecl *method
1170 cling::LookupHelper::NoDiagnostics);
1171 if (method && method->getAccess() != clang::AS_public) {
1185 const cling::Interpreter& interp)
1187 if (!cl)
return false;
1189 if (cl->hasUserDeclaredDestructor()) {
1191 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
1192 clang::CXXDestructorDecl *
dest = cl->getDestructor();
1194 return (
dest->getAccess() == clang::AS_public);
1206 const char *methodname,
1208 const cling::Interpreter &interp,
1211 const clang::CXXMethodDecl *method
1213 diagnose ? cling::LookupHelper::WithDiagnostics
1214 : cling::LookupHelper::NoDiagnostics);
1215 return (method && method->getAccess() == clang::AS_public);
1226 const char *
proto =
"TDirectory*";
1227 const char *
name =
"DirectoryAutoAdd";
1241 const char *
proto =
"TCollection*,TFileMergeInfo*";
1242 const char *
name =
"Merge";
1255 const char *
proto =
"TCollection*";
1256 const char *
name =
"Merge";
1271 const char *
proto =
"TFileMergeInfo*";
1272 const char *
name =
"ResetAfterMerge";
1282 const clang::CXXRecordDecl* clxx,
1283 const cling::Interpreter &interp,
1286 static const char *
proto =
"TBuffer&";
1288 const clang::CXXMethodDecl *method
1290 cling::LookupHelper::NoDiagnostics);
1291 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1293 return (method && method->getDeclContext() == clxx_as_context
1301 const clang::CXXRecordDecl* clxx,
1302 const cling::Interpreter &interp,
1305 static const char *
proto =
"TBuffer&,TClass*";
1307 const clang::CXXMethodDecl *method
1309 cling::LookupHelper::NoDiagnostics);
1310 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1312 return (method && method->getDeclContext() == clxx_as_context
1342 clang::QualType qualType(&
type,0);
1374 llvm::raw_string_ostream stream(qual_name);
1375 clang::PrintingPolicy policy( cl.getASTContext().getPrintingPolicy() );
1376 policy.SuppressTagKeyword =
true;
1377 policy.SuppressUnwrittenScope =
true;
1379 cl.getNameForDiagnostic(stream,policy,
true);
1382 if ( qual_name ==
"(anonymous " || qual_name ==
"(unnamed" ) {
1383 size_t pos = qual_name.find(
':');
1384 qual_name.erase(0,pos+2);
1400 const clang::Type* declType ( recordDecl.getTypeForDecl() );
1401 clang::QualType qualType(declType,0);
1435 std::stringstream dims;
1436 std::string typenameStr;
1438 const clang::ASTContext& astContext = cl.getASTContext();
1441 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
1449 typenameStr.clear();
1453 clang::QualType fieldType(field_iter->getType());
1454 if (fieldType->isConstantArrayType()) {
1455 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(fieldType.getTypePtr());
1457 dims <<
"[" << arrayType->getSize().getLimitedValue() <<
"]";
1458 fieldType = arrayType->getElementType();
1459 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1469 for(clang::CXXRecordDecl::base_class_const_iterator iter = cl.bases_begin(), end = cl.bases_end();
1472 std::string basename( iter->getType()->getAsCXXRecordDecl()->getNameAsString() );
1482 const cling::Interpreter &interp,
1485 return interp.getLookupHelper().findFunctionProto(cinfo, method,
proto,
1486 diagnose ? cling::LookupHelper::WithDiagnostics
1487 : cling::LookupHelper::NoDiagnostics);
1521 clang::SourceLocation sourceLocation = decl->getLocation();
1522 clang::SourceManager& sourceManager = decl->getASTContext().getSourceManager();
1524 if (!sourceLocation.isValid() ) {
1528 if (!sourceLocation.isFileID()) {
1529 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
1532 if (sourceLocation.isValid() && sourceLocation.isFileID()) {
1533 return sourceManager.getLineNumber(sourceManager.getFileID(sourceLocation),sourceManager.getFileOffset(sourceLocation));
1546 while (llvm::isa<clang::PointerType>(instanceType.getTypePtr())
1547 || llvm::isa<clang::ReferenceType>(instanceType.getTypePtr()))
1549 instanceType = instanceType->getPointeeType();
1552 const clang::ElaboratedType* etype
1553 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
1555 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
1568 const clang::CXXRecordDecl* clxx = instanceType->getAsCXXRecordDecl();
1569 if (clxx && clxx->getTemplateSpecializationKind() != clang::TSK_Undeclared) {
1571 const clang::TemplateSpecializationType* TST
1572 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
1579 for(clang::TemplateSpecializationType::iterator
1580 I = TST->begin(), E = TST->end();
1583 if (
I->getKind() == clang::TemplateArgument::Type) {
1598 const cling::Interpreter &interp,
1601 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1602 if (!clxx || clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return false;
1604 clang::QualType instanceType = interp.getLookupHelper().findType(cl.
GetNormalizedName(),
1605 cling::LookupHelper::WithDiagnostics);
1606 if (instanceType.isNull()) {
1619 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(attribute);
1624 attrString = annAttr->getAnnotation().str();
1633 size_t substrFound (attributeStr.find(propNames::separator));
1634 if (substrFound==std::string::npos) {
1638 size_t EndPart1 = attributeStr.find_first_of(propNames::separator) ;
1639 attrName = attributeStr.substr(0, EndPart1);
1640 const int separatorLength(propNames::separator.
size());
1641 attrValue = attributeStr.substr(EndPart1 + separatorLength);
1649 std::string attrString;
1651 if (0!=ret)
return ret;
1659 const std::string& propName,
1660 std::string& propValue)
1662 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1663 attrIt!=decl.attr_end();++attrIt){
1664 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1665 if (!annAttr)
continue;
1667 llvm::StringRef attribute = annAttr->getAnnotation();
1668 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(propNames::separator.c_str());
1669 if (split.first != propName.c_str())
continue;
1671 propValue = split.second.str();
1682 const std::string& propName,
1685 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1686 attrIt!=decl.attr_end();++attrIt){
1687 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1688 if (!annAttr)
continue;
1690 llvm::StringRef attribute = annAttr->getAnnotation();
1691 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(propNames::separator.c_str());
1692 if (split.first != propName.c_str())
continue;
1694 return split.second.getAsInteger(10,propValue);
1705 const clang::CXXRecordDecl *decl,
1706 const cling::Interpreter &interp,
1709 bool& needCollectionProxy)
1713 std::string mappedname;
1715 std::string csymbol = classname;
1723 csymbol.insert(0,
"::");
1729 bool isStd = TMetaUtils::IsStdClass(*decl);
1730 const cling::LookupHelper& lh = interp.getLookupHelper();
1731 bool isString = TMetaUtils::IsOfType(*decl,
"std::string",lh);
1733 bool isStdNotString = isStd && !isString;
1735 finalString <<
"namespace ROOT {" <<
"\n";
1739 finalString <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();\n"
1740 <<
" static void " << mappedname.c_str() <<
"_TClassManip(TClass*);\n";
1746 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p = nullptr);" <<
"\n";
1750 finalString <<
" static void *newArray_";
1751 finalString << mappedname.c_str();
1752 finalString <<
"(Long_t size, void *p);";
1753 finalString <<
"\n";
1758 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";
1761 finalString <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *obj, TDirectory *dir);" <<
"\n";
1764 finalString <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj);" <<
"\n";
1767 finalString <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass*);" <<
"\n";
1770 finalString <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj, TCollection *coll,TFileMergeInfo *info);" <<
"\n";
1773 finalString <<
" static void reset_" << mappedname.c_str() <<
"(void *obj, TFileMergeInfo *info);" <<
"\n";
1780 ROOT::SchemaRuleClassMap_t::iterator rulesIt1 =
ROOT::gReadRules.find( classname.c_str() );
1781 ROOT::SchemaRuleClassMap_t::iterator rulesIt2 =
ROOT::gReadRawRules.find( classname.c_str() );
1792 finalString <<
"\n // Schema evolution read functions\n";
1793 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt1->second.begin();
1794 while( rIt != rulesIt1->second.end() ) {
1800 std::string error_string;
1802 Warning(
nullptr,
"%s", error_string.c_str());
1803 rIt = rulesIt1->second.erase(rIt);
1811 if( rIt->find(
"code" ) != rIt->end() ) {
1827 finalString <<
"\n // Schema evolution read raw functions\n";
1828 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt2->second.begin();
1829 while( rIt != rulesIt2->second.end() ) {
1835 std::string error_string;
1837 Warning(
nullptr,
"%s", error_string.c_str());
1838 rIt = rulesIt2->second.erase(rIt);
1846 if( rIt->find(
"code" ) == rIt->end() )
1854 finalString <<
"\n" <<
" // Function generating the singleton type initializer" <<
"\n";
1856 finalString <<
" static TGenericClassInfo *GenerateInitInstanceLocal(const " << csymbol <<
"*)" <<
"\n" <<
" {" <<
"\n";
1858 finalString <<
" " << csymbol <<
" *ptr = nullptr;" <<
"\n";
1862 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< " << csymbol <<
" >(nullptr);" <<
"\n";
1865 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol <<
"));" <<
"\n";
1867 finalString <<
" static ::ROOT::TGenericClassInfo " <<
"\n" <<
" instance(\"" << classname.c_str() <<
"\", ";
1870 finalString << csymbol <<
"::Class_Version(), ";
1872 finalString <<
"2, ";
1874 finalString <<
"-2, ";
1880 static const char *versionFunc =
"GetClassVersion";
1884 std::string
proto = classname +
"*";
1885 const clang::Decl* ctxt = llvm::dyn_cast<clang::Decl>((*cl).getDeclContext());
1886 const clang::FunctionDecl *methodinfo
1888 interp, cling::LookupHelper::NoDiagnostics);
1896 finalString <<
"GetClassVersion< ";
1897 finalString << classname.c_str();
1898 finalString <<
" >(), ";
1907 for (
unsigned int i=0; i<
filename.length(); i++) {
1912 <<
"," <<
"\n" <<
" typeid(" << csymbol
1913 <<
"), ::ROOT::Internal::DefineBehavior(ptr, ptr)," <<
"\n" <<
" ";
1916 finalString <<
"&" << csymbol <<
"::Dictionary, ";
1918 finalString <<
"&" << mappedname <<
"_Dictionary, ";
1922 TClassTable__kHasCustomStreamerMember = 0x10
1927 rootflag = rootflag | TClassTable__kHasCustomStreamerMember;
1929 finalString <<
"isa_proxy, " << rootflag <<
"," <<
"\n" <<
" sizeof(" << csymbol <<
") );" <<
"\n";
1931 finalString <<
" instance.SetNew(&new_" << mappedname.c_str() <<
");" <<
"\n";
1933 finalString <<
" instance.SetNewArray(&newArray_" << mappedname.c_str() <<
");" <<
"\n";
1936 finalString <<
" instance.SetDelete(&delete_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDeleteArray(&deleteArray_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDestructor(&destruct_" << mappedname.c_str() <<
");" <<
"\n";
1939 finalString <<
" instance.SetDirectoryAutoAdd(&directoryAutoAdd_" << mappedname.c_str() <<
");" <<
"\n";
1943 finalString <<
" instance.SetStreamerFunc(&streamer_" << mappedname.c_str() <<
");" <<
"\n";
1947 finalString <<
" instance.SetConvStreamerFunc(&conv_streamer_" << mappedname.c_str() <<
");" <<
"\n";
1950 finalString <<
" instance.SetMerge(&merge_" << mappedname.c_str() <<
");" <<
"\n";
1953 finalString <<
" instance.SetResetAfterMerge(&reset_" << mappedname.c_str() <<
");" <<
"\n";
1956 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
"Pushback" <<
"<Internal::TStdBitsetHelper< " << classname.c_str() <<
" > >()));" <<
"\n";
1958 needCollectionProxy =
true;
1959 }
else if (stl != 0 &&
1962 int idx = classname.find(
"<");
1964 const char* methodTCP =
nullptr;
1970 methodTCP=
"Pushback";
1973 methodTCP=
"Pushfront";
1979 methodTCP=
"MapInsert";
1991 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << methodTCP <<
"< " << classNameForIO.c_str() <<
" >()));" <<
"\n";
1993 needCollectionProxy =
true;
2001 finalString <<
"\n" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2008 finalString <<
"\n" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2018 finalString <<
"\n" <<
" ::ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
2022 finalString <<
"\n" <<
" // the io read rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrules(" << rulesIt1->second.size() <<
");" <<
"\n";
2024 finalString <<
" instance.SetReadRules( readrules );" <<
"\n";
2028 finalString <<
"\n" <<
" // the io read raw rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrawrules(" << rulesIt2->second.size() <<
");" <<
"\n";
2030 finalString <<
" instance.SetReadRawRules( readrawrules );" <<
"\n";
2033 finalString <<
" return &instance;" <<
"\n" <<
" }" <<
"\n";
2037 finalString <<
" TGenericClassInfo *GenerateInitInstance(const " << csymbol <<
"*)" <<
"\n" <<
" {\n return GenerateInitInstanceLocal(static_cast<" << csymbol <<
"*>(nullptr));\n }" <<
"\n";
2040 finalString <<
" // Static variable to force the class initialization" <<
"\n";
2044 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstanceLocal(static_cast<const " << csymbol <<
"*>(nullptr)); R__UseDummy(_R__UNIQUE_DICT_(Init));" <<
"\n";
2047 finalString <<
"\n" <<
" // Dictionary for non-ClassDef classes" <<
"\n"
2048 <<
" static TClass *" << mappedname <<
"_Dictionary() {\n"
2049 <<
" TClass* theClass ="
2050 <<
"::ROOT::GenerateInitInstanceLocal(static_cast<const " << csymbol <<
"*>(nullptr))->GetClass();\n"
2051 <<
" " << mappedname <<
"_TClassManip(theClass);\n";
2052 finalString <<
" return theClass;\n";
2053 finalString <<
" }\n\n";
2057 std::string manipString;
2058 std::string attribute_s;
2059 std::string attrName, attrValue;
2061 bool attrMapExtracted =
false;
2062 if (decl->hasAttrs()){
2064 for (clang::Decl::attr_iterator attrIt = decl->attr_begin();
2065 attrIt!=decl->attr_end();++attrIt){
2072 if (attrName ==
"name" ||
2073 attrName ==
"pattern" ||
2074 attrName ==
"rootmap")
continue;
2080 if (!attrMapExtracted){
2081 manipString+=
" theClass->CreateAttributeMap();\n";
2082 manipString+=
" TDictAttributeMap* attrMap( theClass->GetAttributeMap() );\n";
2083 attrMapExtracted=
true;
2085 manipString+=
" attrMap->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2091 for(clang::CXXRecordDecl::decl_iterator internalDeclIt = decl->decls_begin();
2092 internalDeclIt != decl->decls_end(); ++internalDeclIt){
2093 if (!(!(*internalDeclIt)->isImplicit()
2094 && (clang::isa<clang::FieldDecl>(*internalDeclIt) ||
2095 clang::isa<clang::VarDecl>(*internalDeclIt))))
continue;
2098 if (!internalDeclIt->hasAttrs())
continue;
2100 attrMapExtracted =
false;
2101 bool memberPtrCreated =
false;
2103 for (clang::Decl::attr_iterator attrIt = internalDeclIt->attr_begin();
2104 attrIt!=internalDeclIt->attr_end();++attrIt){
2112 clang::NamedDecl* namedInternalDecl = clang::dyn_cast<clang::NamedDecl> (*internalDeclIt);
2113 if (!namedInternalDecl) {
2114 TMetaUtils::Error(
nullptr,
"Cannot convert field declaration to clang::NamedDecl");
2117 const std::string memberName(namedInternalDecl->getName());
2118 const std::string cppMemberName =
"theMember_"+memberName;
2121 const std::string dataMemberCreation=
" TDataMember* "+cppMemberName+
" = theClass->GetDataMember(\""+memberName+
"\");\n";
2130 if (attrName == propNames::comment ||
2131 attrName == propNames::iotype ||
2132 attrName == propNames::ioname )
continue;
2134 if (!memberPtrCreated){
2135 manipString+=dataMemberCreation;
2136 memberPtrCreated=
true;
2139 if (!attrMapExtracted){
2140 manipString+=
" "+cppMemberName+
"->CreateAttributeMap();\n";
2141 manipString+=
" TDictAttributeMap* memberAttrMap_"+memberName+
"( theMember_"+memberName+
"->GetAttributeMap() );\n";
2142 attrMapExtracted=
true;
2145 manipString+=
" memberAttrMap_"+memberName+
"->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2152 finalString <<
" static void " << mappedname <<
"_TClassManip(TClass* " << (manipString.empty() ?
"":
"theClass") <<
"){\n"
2157 finalString <<
"} // end of namespace ROOT" <<
"\n" <<
"\n";
2167 std::string &clsname,
2168 std::string &nsname,
2169 const clang::CXXRecordDecl *cl)
2179 auto ctxt = cl->getEnclosingNamespaceContext();
2180 while(ctxt && ctxt!=cl && ctxt->isInlineNamespace()) {
2181 ctxt = ctxt->getParent();
2184 const clang::NamedDecl *namedCtxt = llvm::dyn_cast<clang::NamedDecl>(ctxt);
2185 if (namedCtxt && namedCtxt!=cl) {
2186 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(namedCtxt);
2187 if (nsdecl && !nsdecl->isAnonymousNamespace()) {
2189 clsname.erase (0, nsname.size() + 2);
2201 const clang::DeclContext *ctxt = cl.getDeclContext();
2202 while(ctxt && !ctxt->isNamespace()) {
2203 ctxt = ctxt->getParent();
2217 int closing_brackets = 0;
2221 if (ctxt && ctxt->isNamespace()) {
2223 const clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(ctxt);
2229 out <<
"namespace " << ns->getNameAsString() <<
" {" << std::endl;
2234 return closing_brackets;
2248 clang::TemplateSpecializationKind kind = cl->getTemplateSpecializationKind();
2249 if (kind == clang::TSK_Undeclared ) {
2252 }
else if (kind == clang::TSK_ExplicitSpecialization) {
2266 const char *
name = which;
2267 const char *
proto =
"size_t";
2268 const char *protoPlacement =
"size_t,void*";
2271 const clang::FunctionDecl *operatornew
2274 cling::LookupHelper::NoDiagnostics);
2275 const clang::FunctionDecl *operatornewPlacement
2277 name, protoPlacement, interp,
2278 cling::LookupHelper::NoDiagnostics);
2280 const clang::DeclContext *ctxtnew =
nullptr;
2281 const clang::DeclContext *ctxtnewPlacement =
nullptr;
2284 ctxtnew = operatornew->getParent();
2286 if (operatornewPlacement) {
2287 ctxtnewPlacement = operatornewPlacement->getParent();
2293 operatornewPlacement
2298 ctxtnew = operatornew->getParent();
2300 if (operatornewPlacement) {
2301 ctxtnewPlacement = operatornewPlacement->getParent();
2304 if (!ctxtnewPlacement) {
2312 if (ctxtnew == ctxtnewPlacement) {
2316 const clang::CXXRecordDecl* clnew = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnew);
2317 const clang::CXXRecordDecl* clnewPlacement = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnewPlacement);
2318 if (!clnew && !clnewPlacement) {
2324 if (clnew && !clnewPlacement) {
2328 if (!clnew && clnewPlacement) {
2333 if (clnew->isDerivedFrom(clnewPlacement)) {
2363 const clang::CXXRecordDecl *decl,
2364 const cling::Interpreter &interp,
2370 std::string mappedname;
2388 classname.insert(0,
"::");
2391 finalString <<
"namespace ROOT {" <<
"\n";
2396 finalString <<
" // Wrappers around operator new" <<
"\n";
2397 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" return p ? ";
2399 finalString <<
"new(p) ";
2400 finalString << classname.c_str();
2401 finalString << args;
2402 finalString <<
" : ";
2404 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2405 finalString << classname.c_str();
2406 finalString << args;
2407 finalString <<
" : ";
2409 finalString <<
"new " << classname.c_str() << args <<
";" <<
"\n";
2410 finalString <<
" }" <<
"\n";
2414 finalString <<
" static void *newArray_";
2415 finalString << mappedname.c_str();
2416 finalString <<
"(Long_t nElements, void *p) {";
2417 finalString <<
"\n";
2418 finalString <<
" return p ? ";
2420 finalString <<
"new(p) ";
2421 finalString << classname.c_str();
2422 finalString <<
"[nElements] : ";
2424 finalString <<
"::new((::ROOT::Internal::TOperatorNewHelper*)p) ";
2425 finalString << classname.c_str();
2426 finalString <<
"[nElements] : ";
2428 finalString <<
"new ";
2429 finalString << classname.c_str();
2430 finalString <<
"[nElements];";
2431 finalString <<
"\n";
2432 finalString <<
" }";
2433 finalString <<
"\n";
2438 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";
2442 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";
2446 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";
2450 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";
2454 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";
2456 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";
2460 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";
2462 finalString <<
"} // end of namespace ROOT for class " << classname.c_str() <<
"\n" <<
"\n";
2469 const cling::Interpreter &interp,
2476 if (version == 0)
return;
2480 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2484 for(clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
2490 Internal::RStl::Instance().GenerateTClassFor( iter->getType(), interp, normCtxt);
2495 for(clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
2499 std::string mTypename;
2505 if (!strcmp(shortTypeName,
"string")) {
2517 Internal::RStl::Instance().GenerateTClassFor(utype, interp, normCtxt);
2527 const clang::Type *rawtype =
m.getType()->getCanonicalTypeInternal().getTypePtr();
2528 if (rawtype->isArrayType()) {
2529 rawtype = rawtype->getBaseElementTypeUnsafe ();
2543 const clang::CXXRecordDecl* CRD = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
2552 if (!funcCV)
return -1;
2555 if (funcCV == (clang::FunctionDecl*)-1)
return 1;
2570 using res_t = std::pair<bool, int>;
2572 const clang::CompoundStmt* FuncBody
2573 = llvm::dyn_cast_or_null<clang::CompoundStmt>(funcCV->getBody());
2575 return res_t{
false, -1};
2576 if (FuncBody->size() != 1) {
2580 return res_t{
false, -1};
2582 const clang::ReturnStmt* RetStmt
2583 = llvm::dyn_cast<clang::ReturnStmt>(FuncBody->body_back());
2585 return res_t{
false, -1};
2586 const clang::Expr* RetExpr = RetStmt->getRetValue();
2592 if (
auto RetRes = RetExpr->getIntegerConstantExpr(funcCV->getASTContext())) {
2593 if (RetRes->isSigned())
2594 return res_t{
true, (
Version_t)RetRes->getSExtValue()};
2595 return res_t{
true, (
Version_t)RetRes->getZExtValue()};
2597 return res_t{
false, -1};
2613 clang::QualType
type =
m.getType();
2616 if (decl)
return TMetaUtils::IsSTLCont(*decl);
2625 clang::QualType
type = base.getType();
2628 if (decl)
return TMetaUtils::IsSTLCont(*decl);
2638 const std::function<
void(
const clang::Module::Header &)> &closure,
2639 bool includeDirectlyUsedModules)
2648 const std::size_t publicHeaderIndex = 4;
2651 const std::size_t maxArrayLength = ((
sizeof module.Headers) / (
sizeof *module.Headers));
2652 static_assert(publicHeaderIndex + 1 == maxArrayLength,
2653 "'Headers' has changed it's size, we need to update publicHeaderIndex");
2658 llvm::SetVector<const clang::Module *> modules;
2659 modules.insert(&module);
2660 for (
size_t i = 0; i < modules.size(); ++i) {
2661 const clang::Module *M = modules[i];
2662 for (
const clang::Module *subModule : M->submodules())
2663 modules.insert(subModule);
2666 for (
const clang::Module *
m : modules) {
2667 if (includeDirectlyUsedModules) {
2668 for (clang::Module *used :
m->DirectUses) {
2673 for (std::size_t i = 0; i < publicHeaderIndex; i++) {
2674 auto &headerList =
m->Headers[i];
2675 for (
const clang::Module::Header &moduleHeader : headerList) {
2676 closure(moduleHeader);
2690 static char t[4096];
2691 static const char* constwd =
"const ";
2692 static const char* constwdend =
"const";
2697 for (s=typeDesc;*s;s++) {
2700 if (lev==0 && *s==
'*')
continue;
2701 if (lev==0 && (strncmp(constwd,s,strlen(constwd))==0
2702 ||strcmp(constwdend,s)==0 ) ) {
2703 s+=strlen(constwd)-1;
2706 if (lev==0 && *s==
' ' && *(s+1)!=
'*') {
p = t;
continue;}
2707 if (
p - t > (
long)
sizeof(t)) {
2708 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2721 const cling::Interpreter& interp)
2726 if (!comment.empty() && comment[0] ==
'!')
2729 clang::QualType
type =
m.getType();
2731 if (
type->isReferenceType()) {
2736 std::string mTypeName =
type.getAsString(
m.getASTContext().getPrintingPolicy());
2737 if (!strcmp(mTypeName.c_str(),
"string") || !strcmp(mTypeName.c_str(),
"string*")) {
2740 if (!strcmp(mTypeName.c_str(),
"std::string") || !strcmp(mTypeName.c_str(),
"std::string*")) {
2748 const clang::Type *rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
2750 if (rawtype->isPointerType()) {
2752 clang::QualType pointee;
2753 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
2755 rawtype = pointee.getTypePtr();
2759 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2764 const clang::CXXRecordDecl *cxxdecl = rawtype->getAsCXXRecordDecl();
2768 if (version > 0)
return true;
2781 const clang::Type *rawtype =
m.getType().getTypePtr();
2784 clang::QualType pointee;
2785 while ( rawtype->isPointerType() && ((pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull()) && pointee.getTypePtr() != rawtype)
2787 rawtype = pointee.getTypePtr();
2801 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2805 return rawtype->getAsCXXRecordDecl();
2814 const cling::Interpreter &interp,
2816 std::ostream& dictStream,
2818 bool isGenreflex=
false)
2820 const clang::CXXRecordDecl* decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2822 if (!decl || !decl->isCompleteDefinition()) {
2826 std::string fullname;
2829 Internal::RStl::Instance().GenerateTClassFor(cl.
GetNormalizedName(), llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl()), interp, normCtxt);
2838 (*WriteStreamerFunc)(cl, interp, normCtxt, dictStream, isGenreflex || cl.RequestStreamerInfo());
2840 ROOT::TMetaUtils::Info(
nullptr,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
2862 const cling::Interpreter &interpreter,
2865 const clang::ASTContext& Ctx = interpreter.getCI()->getASTContext();
2867 clang::QualType originalType = instanceType;
2871 if (llvm::isa<clang::PointerType>(instanceType.getTypePtr())) {
2873 clang::Qualifiers quals = instanceType.getQualifiers();
2874 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2875 if (newPointee != instanceType->getPointeeType()) {
2876 instanceType = Ctx.getPointerType(newPointee);
2878 instanceType = Ctx.getQualifiedType(instanceType, quals);
2880 return instanceType;
2885 if (llvm::isa<clang::ReferenceType>(instanceType.getTypePtr())) {
2887 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(instanceType.getTypePtr());
2888 clang::Qualifiers quals = instanceType.getQualifiers();
2889 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2891 if (newPointee != instanceType->getPointeeType()) {
2894 instanceType = Ctx.getLValueReferenceType(newPointee);
2896 instanceType = Ctx.getRValueReferenceType(newPointee);
2898 instanceType = Ctx.getQualifiedType(instanceType, quals);
2900 return instanceType;
2904 bool prefix_changed =
false;
2905 clang::NestedNameSpecifier *prefix =
nullptr;
2906 clang::Qualifiers prefix_qualifiers = instanceType.getLocalQualifiers();
2907 const clang::ElaboratedType* etype
2908 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
2911 prefix = AddDefaultParametersNNS(Ctx, etype->getQualifier(), interpreter, normCtxt);
2912 prefix_changed = prefix != etype->getQualifier();
2913 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
2919 const clang::TemplateSpecializationType* TST
2920 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
2922 const clang::ClassTemplateSpecializationDecl* TSTdecl
2923 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instanceType.getTypePtr()->getAsCXXRecordDecl());
2935 bool mightHaveChanged =
false;
2936 if (TST && TSTdecl) {
2938 clang::Sema& S = interpreter.getCI()->getSema();
2939 clang::TemplateDecl *Template = TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
2940 clang::TemplateParameterList *Params = Template->getTemplateParameters();
2941 clang::TemplateParameterList::iterator Param = Params->
begin();
2945 unsigned int dropDefault = normCtxt.
GetConfig().DropDefaultArg(*Template);
2947 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
2948 unsigned int Idecl = 0, Edecl = TSTdecl->getTemplateArgs().size();
2949 unsigned int maxAddArg = TSTdecl->getTemplateArgs().size() - dropDefault;
2950 for(clang::TemplateSpecializationType::iterator
2951 I = TST->begin(), E = TST->end();
2953 I!=E ? ++
I :
nullptr, ++Idecl, ++Param) {
2957 if (
I->getKind() == clang::TemplateArgument::Template) {
2958 clang::TemplateName templateName =
I->getAsTemplate();
2959 clang::TemplateDecl* templateDecl = templateName.getAsTemplateDecl();
2961 clang::DeclContext* declCtxt = templateDecl->getDeclContext();
2963 if (declCtxt && !templateName.getAsQualifiedTemplateName()){
2964 clang::NamespaceDecl* ns = clang::dyn_cast<clang::NamespaceDecl>(declCtxt);
2965 clang::NestedNameSpecifier* nns;
2967 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx, ns);
2968 }
else if (clang::TagDecl* TD = llvm::dyn_cast<clang::TagDecl>(declCtxt)) {
2969 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,TD,
false );
2972 desArgs.push_back(*
I);
2975 clang::TemplateName templateNameWithNSS ( Ctx.getQualifiedTemplateName(nns,
false, templateDecl) );
2976 desArgs.push_back(clang::TemplateArgument(templateNameWithNSS));
2977 mightHaveChanged =
true;
2983 if (
I->getKind() != clang::TemplateArgument::Type) {
2984 desArgs.push_back(*
I);
2988 clang::QualType SubTy =
I->getAsType();
2997 if (SubTy != newSubTy) {
2998 mightHaveChanged =
true;
2999 desArgs.push_back(clang::TemplateArgument(newSubTy));
3001 desArgs.push_back(*
I);
3004 }
else if (!isStdDropDefault && Idecl < maxAddArg) {
3006 mightHaveChanged =
true;
3008 const clang::TemplateArgument& templateArg
3009 = TSTdecl->getTemplateArgs().get(Idecl);
3010 if (templateArg.getKind() != clang::TemplateArgument::Type) {
3011 desArgs.push_back(templateArg);
3014 clang::QualType SubTy = templateArg.getAsType();
3016 clang::SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3017 clang::SourceLocation RAngleLoc = TSTdecl->getSourceRange().getBegin();
3019 clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
3022 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
3023 clang::sema::HackForDefaultTemplateArg raii;
3024 bool HasDefaultArgs;
3025 clang::TemplateArgumentLoc ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
3034 if (ArgType.getArgument().isNull()
3035 || ArgType.getArgument().getKind() != clang::TemplateArgument::Type) {
3037 "Template parameter substitution failed for %s around %s\n",
3038 instanceType.getAsString().c_str(), SubTy.getAsString().c_str());
3041 clang::QualType BetterSubTy = ArgType.getArgument().getAsType();
3042 SubTy = cling::utils::Transform::GetPartiallyDesugaredType(Ctx,BetterSubTy,normCtxt.
GetConfig(),
true);
3045 desArgs.push_back(clang::TemplateArgument(SubTy));
3054 if (mightHaveChanged) {
3055 instanceType = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
3057 TST->getCanonicalTypeInternal());
3061 if (!prefix_changed && !mightHaveChanged)
return originalType;
3063 instanceType = Ctx.getElaboratedType(clang::ETK_None,prefix,instanceType);
3064 instanceType = Ctx.getQualifiedType(instanceType,prefix_qualifiers);
3066 return instanceType;
3086 llvm::StringRef title;
3089 if (clang::AnnotateAttr *A =
m.getAttr<clang::AnnotateAttr>())
3090 title = A->getAnnotation();
3102 if (errnum) *errnum =
VALID;
3104 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
3105 size_t rightbracket = title.find(
']');
3106 if (rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
3108 std::string working;
3109 llvm::StringRef indexvar(title.data()+1,rightbracket-1);
3116 size_t indexvarlen = indexvar.size();
3117 for ( i=0; i<indexvarlen; i++) {
3118 if (!isspace(indexvar[i])) {
3119 working += indexvar[i];
3124 const char *tokenlist =
"*+-";
3125 char *current =
const_cast<char*
>(working.c_str());
3126 current = strtok(current,tokenlist);
3130 if (isdigit(current[0])) {
3131 for(i=0;i<strlen(current);i++) {
3132 if (!isdigit(current[i])) {
3137 if (errstr) *errstr = current;
3138 if (errnum) *errnum =
NOT_INT;
3139 return llvm::StringRef();
3144 const clang::CXXRecordDecl *parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext());
3145 const clang::FieldDecl *index1 =
nullptr;
3147 index1 = GetDataMemberFromAll(*parent_clxx, current );
3149 if ( IsFieldDeclInt(index1) ) {
3154 for(clang::RecordDecl::field_iterator field_iter = parent_clxx->field_begin(), end = parent_clxx->field_end();
3158 if ( field_iter->getNameAsString() ==
m.getNameAsString() ) {
3164 if (errstr) *errstr = current;
3165 if (errnum) *errnum =
NOT_DEF;
3166 return llvm::StringRef();
3168 if ( field_iter->getNameAsString() == index1->getNameAsString() ) {
3176 if (errstr) *errstr = current;
3177 if (errnum) *errnum =
NOT_INT;
3178 return llvm::StringRef();
3185 clang::Sema& SemaR =
const_cast<cling::Interpreter&
>(interp).getSema();
3186 index1 = GetDataMemberFromAllParents(SemaR, *parent_clxx, current);
3189 if ( IsFieldDeclInt(index1) ) {
3196 if (errnum) *errnum =
NOT_INT;
3197 if (errstr) *errstr = current;
3201 if (errnum) *errnum =
NOT_INT;
3202 if (errstr) *errstr = current;
3203 return llvm::StringRef();
3205 if ( found && (index1->getAccess() == clang::AS_private) ) {
3208 if (errstr) *errstr = current;
3210 return llvm::StringRef();
3217 if (errstr) *errstr = indexvar;
3218 if (errnum) *errnum =
UNKNOWN;
3219 return llvm::StringRef();
3224 current = strtok(
nullptr, tokenlist);
3240 while((
c = in[i++])) {
3241 const char *repl =
nullptr;
3243 case '+': repl =
"pL";
break;
3244 case '-': repl =
"mI";
break;
3245 case '*': repl =
"mU";
break;
3246 case '/': repl =
"dI";
break;
3247 case '&': repl =
"aN";
break;
3248 case '%': repl =
"pE";
break;
3249 case '|': repl =
"oR";
break;
3250 case '^': repl =
"hA";
break;
3251 case '>': repl =
"gR";
break;
3252 case '<': repl =
"lE";
break;
3253 case '=': repl =
"eQ";
break;
3254 case '~': repl =
"wA";
break;
3255 case '.': repl =
"dO";
break;
3256 case '(': repl =
"oP";
break;
3257 case ')': repl =
"cP";
break;
3258 case '[': repl =
"oB";
break;
3259 case ']': repl =
"cB";
break;
3260 case '!': repl =
"nO";
break;
3261 case ',': repl =
"cO";
break;
3262 case '$': repl =
"dA";
break;
3263 case ' ': repl =
"sP";
break;
3264 case ':': repl =
"cL";
break;
3265 case '"': repl =
"dQ";
break;
3266 case '@': repl =
"aT";
break;
3267 case '\'': repl =
"sQ";
break;
3268 case '\\': repl =
"fI";
break;
3277 auto firstNonNumber = out.find_first_not_of(
"0123456789");
3278 if (firstNonNumber != std::string::npos)
3279 out.replace(0,firstNonNumber,
"");
3282static clang::SourceLocation
3284 clang::SourceLocation sourceLoc) {
3286 if (!sourceLoc.isFileID()) {
3287 return sourceManager.getExpansionRange(sourceLoc).getEnd();
3296 const cling::Interpreter& interp)
3326 using namespace clang;
3327 SourceLocation headerLoc = decl.getLocation();
3329 static const char invalidFilename[] =
"";
3330 if (!headerLoc.isValid())
return invalidFilename;
3332 HeaderSearch& HdrSearch = interp.getCI()->getPreprocessor().getHeaderSearchInfo();
3334 SourceManager& sourceManager = decl.getASTContext().getSourceManager();
3336 FileID headerFID = sourceManager.getFileID(headerLoc);
3337 SourceLocation includeLoc
3339 sourceManager.getIncludeLoc(headerFID));
3341 const FileEntry *headerFE = sourceManager.getFileEntryForID(headerFID);
3342 while (includeLoc.isValid() && sourceManager.isInSystemHeader(includeLoc)) {
3343 const DirectoryLookup *foundDir =
nullptr;
3346 assert(headerFE &&
"Couldn't find FileEntry from FID!");
3348 = HdrSearch.LookupFile(llvm::sys::path::filename(headerFE->getName()),
3350 true ,
nullptr, foundDir,
3351 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3359 headerFID = sourceManager.getFileID(includeLoc);
3360 headerFE = sourceManager.getFileEntryForID(headerFID);
3365 if (interp.getCI()->getLangOpts().Modules && !headerFE) {
3366 assert(decl.isFirstDecl() &&
"Couldn't trace back include from a decl"
3367 " that is not from an AST file");
3368 assert(StringRef(includeLoc.printToString(sourceManager)).startswith(
"<module-includes>"));
3372 sourceManager.getIncludeLoc(headerFID));
3375 if (!headerFE)
return invalidFilename;
3377 llvm::SmallString<256> headerFileName(headerFE->getName());
3380 llvm::sys::path::remove_dots(headerFileName,
true);
3391 bool isAbsolute = llvm::sys::path::is_absolute(headerFileName);
3392 llvm::Optional<clang::FileEntryRef> FELong;
3394 for (llvm::sys::path::const_iterator
3395 IDir = llvm::sys::path::begin(headerFileName),
3396 EDir = llvm::sys::path::end(headerFileName);
3397 !FELong && IDir != EDir; ++IDir) {
3403 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3404 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3405 assert(trailingPart.data() + trailingPart.size()
3406 == headerFileName.data() + headerFileName.size()
3407 &&
"Mismatched partitioning of file name!");
3408 const DirectoryLookup* FoundDir =
nullptr;
3409 FELong = HdrSearch.LookupFile(trailingPart, SourceLocation(),
3410 true ,
nullptr, FoundDir,
3411 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3419 return invalidFilename;
3423 for (llvm::sys::path::reverse_iterator
3424 IDir = llvm::sys::path::rbegin(headerFileName),
3425 EDir = llvm::sys::path::rend(headerFileName);
3426 IDir != EDir; ++IDir) {
3427 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3428 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3429 assert(trailingPart.data() + trailingPart.size()
3430 == headerFileName.data() + headerFileName.size()
3431 &&
"Mismatched partitioning of file name!");
3432 const DirectoryLookup* FoundDir =
nullptr;
3435 if (HdrSearch.LookupFile(trailingPart, SourceLocation(),
3436 true ,
nullptr, FoundDir,
3437 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3440 nullptr,
nullptr ) == FELong) {
3441 return trailingPart.str();
3445 return invalidFilename;
3451 const clang::QualType &qtype,
3452 const clang::ASTContext &astContext)
3454 std::string fqname = cling::utils::TypeName::GetFullyQualifiedName(qtype, astContext);
3463 const clang::QualType &qtype,
3464 const cling::Interpreter &interpreter)
3469 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3473 interpreter.getCI()->getASTContext());
3481 clang::ClassTemplateDecl*& ctd,
3482 clang::ClassTemplateSpecializationDecl*& ctsd)
3484 using namespace clang;
3485 const Type* theType = qt.getTypePtr();
3492 if (theType->isPointerType()) {
3496 if (
const RecordType* rType = llvm::dyn_cast<RecordType>(theType)) {
3497 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(rType->getDecl());
3499 ctd = ctsd->getSpecializedTemplate();
3504 if (
const SubstTemplateTypeParmType* sttpType = llvm::dyn_cast<SubstTemplateTypeParmType>(theType)){
3509 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(qt->getAsCXXRecordDecl());
3511 ctd = ctsd->getSpecializedTemplate();
3526 using namespace clang;
3527 ClassTemplateSpecializationDecl* ctsd;
3528 ClassTemplateDecl* ctd;
3542 using namespace clang;
3543 TemplateName theTemplateName;
3545 const Type* theType = qt.getTypePtr();
3547 if (
const TemplateSpecializationType* tst = llvm::dyn_cast_or_null<const TemplateSpecializationType>(theType)) {
3548 theTemplateName = tst->getTemplateName();
3551 theTemplateName = TemplateName(ctd);
3554 return theTemplateName;
3560 llvm::SmallVectorImpl<clang::TemplateArgument>& preceedingTArgs,
3561 const clang::NamedDecl& tPar,
3562 const cling::Interpreter& interp,
3566 using namespace clang;
3569 TemplateTypeParmDecl* ttpdPtr =
const_cast<TemplateTypeParmDecl*
>(llvm::dyn_cast<TemplateTypeParmDecl>(&tPar));
3570 if (!ttpdPtr)
return false;
3571 if (!ttpdPtr->hasDefaultArgument())
return false;
3574 QualType tParQualType = ttpdPtr->getDefaultArgument();
3575 const QualType tArgQualType = tArg.getAsType();
3582 if (tParQualType.getTypePtr() == tArgQualType.getTypePtr())
return true;
3593 const clang::ElaboratedType* etype
3594 = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3596 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3597 etype = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3600 const TemplateSpecializationType* tst =
3601 llvm::dyn_cast<TemplateSpecializationType>(tParQualType.getTypePtr());
3606 ClassTemplateSpecializationDecl* TSTdecl
3607 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(tArgQualType->getAsCXXRecordDecl());
3612 TemplateDecl *Template = tst->getTemplateName().getAsTemplateDecl();
3615 SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3618 SourceLocation LAngleLoc = TSTdecl->getSourceRange().getBegin();
3623 TemplateArgument newArg = tArg;
3625 clang::Sema& S = interp.getCI()->getSema();
3626 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
3627 clang::sema::HackForDefaultTemplateArg raii;
3628 bool HasDefaultArgs;
3629 TemplateArgumentLoc defTArgLoc = S.SubstDefaultTemplateArgumentIfAvailable(Template,
3637 newArg = defTArgLoc.getArgument();
3638 if (newArg.isNull() ||
3639 newArg.getKind() != clang::TemplateArgument::Type) {
3641 "Template parameter substitution failed!");
3644 ClassTemplateSpecializationDecl* nTSTdecl
3645 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(newArg.getAsType()->getAsCXXRecordDecl());
3648 isEqual = (nTSTdecl && nTSTdecl->getMostRecentDecl() == TSTdecl->getMostRecentDecl()) ||
3649 (tParQualType.getTypePtr() == newArg.getAsType().getTypePtr());
3661 const clang::NamedDecl& tPar)
3663 using namespace clang;
3664 const NonTypeTemplateParmDecl* nttpdPtr = llvm::dyn_cast<NonTypeTemplateParmDecl>(&tPar);
3665 if (!nttpdPtr)
return false;
3666 const NonTypeTemplateParmDecl& nttpd = *nttpdPtr;
3668 if (!nttpd.hasDefaultArgument())
3672 llvm::APSInt defaultValueAPSInt(64,
false);
3673 if (Expr* defArgExpr = nttpd.getDefaultArgument()) {
3674 const ASTContext& astCtxt = nttpdPtr->getASTContext();
3675 if (
auto Value = defArgExpr->getIntegerConstantExpr(astCtxt))
3676 defaultValueAPSInt = *
Value;
3679 const int value = tArg.getAsIntegral().getLimitedValue();
3682 return value == defaultValueAPSInt;
3692 using namespace clang;
3693 if (!nDecl)
return false;
3694 if (
const TemplateTypeParmDecl* ttpd = llvm::dyn_cast<TemplateTypeParmDecl>(nDecl))
3695 return ttpd->hasDefaultArgument();
3696 if (
const NonTypeTemplateParmDecl* nttpd = llvm::dyn_cast<NonTypeTemplateParmDecl>(nDecl))
3697 return nttpd->hasDefaultArgument();
3702static void KeepNParams(clang::QualType& normalizedType,
3703 const clang::QualType& vanillaType,
3704 const cling::Interpreter& interp,
3709 const clang::TemplateArgument &tArg,
3710 const cling::Interpreter& interp,
3712 const clang::ASTContext& astCtxt)
3715 using namespace clang;
3722 if (tArg.getKind() == clang::TemplateArgument::Type) {
3723 QualType thisNormQualType = normTArg.getAsType();
3724 QualType thisArgQualType = tArg.getAsType();
3729 normTArg = TemplateArgument(thisNormQualType);
3730 return (thisNormQualType != thisArgQualType);
3731 }
else if (normTArg.getKind() == clang::TemplateArgument::Pack) {
3732 assert( tArg.getKind() == clang::TemplateArgument::Pack );
3734 SmallVector<TemplateArgument, 2> desArgs;
3735 bool mightHaveChanged =
true;
3736 for (
auto I = normTArg.pack_begin(), E = normTArg.pack_end(),
3737 FI = tArg.pack_begin(), FE = tArg.pack_end();
3738 I != E && FI != FE; ++
I, ++FI)
3740 TemplateArgument pack_arg(*
I);
3742 desArgs.push_back(pack_arg);
3744 if (mightHaveChanged) {
3745 ASTContext &mutableCtx(
const_cast<ASTContext&
>(astCtxt) );
3746 normTArg = TemplateArgument::CreatePackCopy(mutableCtx, desArgs);
3748 return mightHaveChanged;
3759 const clang::QualType& vanillaType,
3760 const cling::Interpreter& interp,
3764 using namespace clang;
3768 ClassTemplateSpecializationDecl* ctsd;
3769 ClassTemplateDecl* ctd;
3770 if (! QualType2Template(vanillaType, ctd, ctsd)) return ;
3776 QualType originalNormalizedType = normalizedType;
3778 const ASTContext& astCtxt = ctsd->getASTContext();
3783 if (llvm::isa<clang::PointerType>(normalizedType.getTypePtr())) {
3785 clang::Qualifiers quals = normalizedType.getQualifiers();
3786 auto valNormalizedType = normalizedType->getPointeeType();
3787 KeepNParams(valNormalizedType,vanillaType, interp, normCtxt);
3788 normalizedType = astCtxt.getPointerType(valNormalizedType);
3790 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3796 if (llvm::isa<clang::ReferenceType>(normalizedType.getTypePtr())) {
3798 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(normalizedType.getTypePtr());
3799 clang::Qualifiers quals = normalizedType.getQualifiers();
3800 auto valNormType = normalizedType->getPointeeType();
3801 KeepNParams(valNormType, vanillaType, interp, normCtxt);
3805 normalizedType = astCtxt.getLValueReferenceType(valNormType);
3807 normalizedType = astCtxt.getRValueReferenceType(valNormType);
3809 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3814 bool prefix_changed =
false;
3815 clang::NestedNameSpecifier* prefix =
nullptr;
3816 clang::Qualifiers prefix_qualifiers = normalizedType.getLocalQualifiers();
3817 const clang::ElaboratedType* etype
3818 = llvm::dyn_cast<clang::ElaboratedType>(normalizedType.getTypePtr());
3822 prefix = AddDefaultParametersNNS(astCtxt, etype->getQualifier(), interp, normCtxt);
3823 prefix_changed = prefix != etype->getQualifier();
3824 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3830 const clang::ClassTemplateDecl* ctdWithDefaultArgs = ctd;
3831 for (
const RedeclarableTemplateDecl* rd: ctdWithDefaultArgs->redecls()) {
3832 clang::TemplateParameterList* tpl = rd->getTemplateParameters();
3833 if (tpl->getMinRequiredArguments () < tpl->size()) {
3834 ctdWithDefaultArgs = llvm::dyn_cast<clang::ClassTemplateDecl>(rd);
3839 if (!ctdWithDefaultArgs) {
3840 Error(
"KeepNParams",
"Not found template default arguments\n");
3841 normalizedType=originalNormalizedType;
3845 TemplateParameterList* tParsPtr = ctdWithDefaultArgs->getTemplateParameters();
3846 const TemplateParameterList& tPars = *tParsPtr;
3847 const TemplateArgumentList& tArgs = ctsd->getTemplateArgs();
3850 TemplateName theTemplateName = ExtractTemplateNameFromQualType(normalizedType);
3851 if (theTemplateName.isNull()) {
3852 normalizedType=originalNormalizedType;
3856 const TemplateSpecializationType* normalizedTst =
3857 llvm::dyn_cast<TemplateSpecializationType>(normalizedType.getTypePtr());
3858 if (!normalizedTst) {
3859 normalizedType=originalNormalizedType;
3863 const clang::ClassTemplateSpecializationDecl* TSTdecl
3864 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(normalizedType.getTypePtr()->getAsCXXRecordDecl());
3865 bool isStdDropDefault = TSTdecl && IsStdDropDefaultClass(*TSTdecl);
3872 llvm::SmallVector<TemplateArgument, 4> argsToKeep;
3874 const int nArgs = tArgs.size();
3875 const int nNormArgs = normalizedTst->getNumArgs();
3877 bool mightHaveChanged =
false;
3880 for (
int formal = 0, inst = 0; formal != nArgs; ++formal, ++inst) {
3881 const NamedDecl* tParPtr = tPars.getParam(formal);
3883 Error(
"KeepNParams",
"The parameter number %s is null.\n", formal);
3890 if (formal == nNormArgs || inst == nNormArgs)
break;
3892 const TemplateArgument& tArg = tArgs.get(formal);
3893 TemplateArgument normTArg(normalizedTst->getArgs()[inst]);
3895 bool shouldKeepArg = nArgsToKeep < 0 || inst < nArgsToKeep;
3896 if (isStdDropDefault) shouldKeepArg =
false;
3905 if ( tParPtr->isTemplateParameterPack() ) {
3910 for( ; inst != nNormArgs; ++inst) {
3911 normTArg = normalizedTst->getArgs()[inst];
3913 argsToKeep.push_back(normTArg);
3919 argsToKeep.push_back(normTArg);
3922 if (!isStdDropDefault) {
3924 mightHaveChanged =
true;
3934 auto argKind = tArg.getKind();
3935 if (argKind == clang::TemplateArgument::Type){
3937 equal =
areEqualTypes(tArg, argsToKeep, *tParPtr, interp, normCtxt);
3938 }
else if (argKind == clang::TemplateArgument::Integral){
3943 argsToKeep.push_back(normTArg);
3945 mightHaveChanged =
true;
3951 if (!prefix_changed && !mightHaveChanged) {
3952 normalizedType = originalNormalizedType;
3957 if (mightHaveChanged) {
3958 Qualifiers qualifiers = normalizedType.getLocalQualifiers();
3959 normalizedType = astCtxt.getTemplateSpecializationType(theTemplateName,
3961 normalizedType.getTypePtr()->getCanonicalTypeInternal());
3962 normalizedType = astCtxt.getQualifiedType(normalizedType, qualifiers);
3968 normalizedType = astCtxt.getElaboratedType(clang::ETK_None,prefix,normalizedType);
3969 normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
3983 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3986 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3987 clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt,
type, normCtxt.
GetConfig(),
true );
3995 return normalizedType;
4009 if (
type.isNull()) {
4016 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
4017 clang::PrintingPolicy policy(ctxt.getPrintingPolicy());
4018 policy.SuppressTagKeyword =
true;
4019 policy.SuppressScope =
true;
4020 policy.AnonymousTagLocations =
false;
4025 std::string normalizedNameStep1;
4028 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
4029 normalizedType.getAsStringInternal(normalizedNameStep1,policy);
4039 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
4040 norm_name.erase(0,2);
4048 const clang::TypeDecl* typeDecl,
4049 const cling::Interpreter &interpreter)
4052 const clang::Sema &sema = interpreter.getSema();
4053 clang::ASTContext& astCtxt = sema.getASTContext();
4054 clang::QualType qualType = astCtxt.getTypeDeclType(typeDecl);
4063std::pair<std::string,clang::QualType>
4065 const cling::Interpreter &interpreter,
4069 std::string thisTypeName;
4070 GetNormalizedName(thisTypeName, thisType, interpreter, normCtxt );
4073 if (!hasChanged)
return std::make_pair(thisTypeName,thisType);
4077 "Name changed from %s to %s\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
4080 auto& lookupHelper = interpreter.getLookupHelper();
4082 const clang::Type* typePtrForIO;
4083 lookupHelper.findScope(thisTypeNameForIO,
4084 cling::LookupHelper::DiagSetting::NoDiagnostics,
4088 if (!typePtrForIO) {
4090 "Type not found: %s.",thisTypeNameForIO.c_str());
4093 clang::QualType typeForIO(typePtrForIO,0);
4096 if (!typeForIO->isRecordType()) {
4097 return std::make_pair(thisTypeNameForIO,typeForIO);
4100 auto thisDeclForIO = typeForIO->getAsCXXRecordDecl();
4101 if (!thisDeclForIO) {
4103 "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());
4104 return std::make_pair(thisTypeName,thisType);
4107 return std::make_pair(thisTypeNameForIO,typeForIO);
4113 const cling::Interpreter &interpreter,
4125 std::string dictFileName(moduleName);
4126 dictFileName +=
"_rdict.pcm";
4127 return dictFileName;
4131 llvm::errs() << llvm::StringRef(commentStart, 80) <<
'\n';
4157 clang::SourceManager& sourceManager = decl.getASTContext().getSourceManager();
4158 clang::SourceLocation sourceLocation = decl.getEndLoc();
4161 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
4169 if (!decl.hasOwningModule() && sourceManager.isLoadedSourceLocation(sourceLocation)) {
4175 const char *commentStart = sourceManager.getCharacterData(sourceLocation, &invalid);
4179 bool skipToSemi =
true;
4180 if (
const clang::FunctionDecl* FD = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
4181 if (FD->isImplicit()) {
4185 if (FD->isExplicitlyDefaulted() || FD->isDeletedAsWritten()) {
4189 }
else if (FD->doesThisDeclarationHaveABody()) {
4192 assert((decl.getEndLoc() != sourceLocation || *commentStart ==
'}'
4194 &&
"Expected macro or end of body at '}'");
4195 if (*commentStart) ++commentStart;
4198 while (*commentStart && isspace(*commentStart)
4199 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4202 if (*commentStart ==
';') ++commentStart;
4206 }
else if (
const clang::EnumConstantDecl* ECD
4207 = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
4209 if (ECD->getNextDeclInContext())
4210 while (*commentStart && *commentStart !=
',' && *commentStart !=
'\r' && *commentStart !=
'\n')
4218 while (*commentStart && *commentStart !=
';' && *commentStart !=
'\r' && *commentStart !=
'\n')
4220 if (*commentStart ==
';') ++commentStart;
4224 while ( *commentStart && isspace(*commentStart)
4225 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4229 if (commentStart[0] !=
'/' ||
4230 (commentStart[1] !=
'/' && commentStart[1] !=
'*')) {
4240 unsigned int skipChars = 2;
4241 if (commentStart[0] ==
'/' &&
4242 commentStart[1] ==
'/' &&
4243 (commentStart[2] ==
'/' || commentStart[2] ==
'!') &&
4244 commentStart[3] ==
'<') {
4246 }
else if (commentStart[0] ==
'/' &&
4247 commentStart[1] ==
'*' &&
4248 (commentStart[2] ==
'*' || commentStart[2] ==
'!') &&
4249 commentStart[3] ==
'<') {
4253 commentStart += skipChars;
4256 while ( *commentStart && isspace(*commentStart)
4257 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4260 const char* commentEnd = commentStart;
4262 while (*commentEnd && *commentEnd !=
'\n' && *commentEnd !=
'\r') {
4268 while (commentEnd > commentStart && isspace(commentEnd[-1])) {
4274 unsigned offset = commentStart - sourceManager.getCharacterData(sourceLocation);
4275 *loc = sourceLocation.getLocWithOffset(
offset - 1);
4278 return llvm::StringRef(commentStart, commentEnd - commentStart);
4286 if (!decl)
return false;
4288 auto& sema = interpreter.getCI()->getSema();
4289 auto maybeMacroLoc = decl->getLocation();
4291 if (!maybeMacroLoc.isMacroID())
return false;
4293 static const std::vector<std::string> signatures =
4294 {
"ClassDef",
"ClassDefOverride",
"ClassDefNV",
"ClassDefInline",
"ClassDefInlineOverride",
"ClassDefInlineNV" };
4296 for (
auto &
name : signatures)
4297 if (sema.findMacroSpelling(maybeMacroLoc,
name))
4311 clang::SourceLocation *loc,
4312 const cling::Interpreter &interpreter)
4314 using namespace clang;
4316 const Decl* DeclFileLineDecl
4317 = interpreter.getLookupHelper().findFunctionProto(&decl,
"DeclFileLine",
"",
4318 cling::LookupHelper::NoDiagnostics);
4322 SourceLocation commentSLoc;
4324 if (comment.size()) {
4331 return llvm::StringRef();
4340 const clang::Type *rawtype =
type.getTypePtr();
4343 if (rawtype->isElaboratedTypeSpecifier() ) {
4344 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4346 if (rawtype->isArrayType()) {
4347 rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
4349 if (rawtype->isPointerType() || rawtype->isReferenceType() ) {
4351 clang::QualType pointee;
4352 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
4354 rawtype = pointee.getTypePtr();
4356 if (rawtype->isElaboratedTypeSpecifier() ) {
4357 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4359 if (rawtype->isArrayType()) {
4360 rawtype = rawtype->getBaseElementTypeUnsafe ();
4364 if (rawtype->isArrayType()) {
4365 rawtype = rawtype->getBaseElementTypeUnsafe ();
4375 return cling::utils::Analyze::IsStdClass(cl);
4385 if (cling::utils::Analyze::IsStdClass(cl)) {
4386 static const char *names[] =
4387 {
"shared_ptr",
"__shared_ptr",
4388 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4389 llvm::StringRef clname(cl.getName());
4390 for(
auto &&
name : names) {
4391 if (clname ==
name)
return true;
4401 const clang::CXXRecordDecl ¤tCl)
4404 if (&cl == ¤tCl)
return true;
4406 const clang::CXXRecordDecl* previous = currentCl.getPreviousDecl();
4409 if (
nullptr == previous){
4428 const clang::CXXRecordDecl *thisDecl =
4429 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(typ, cling::LookupHelper::WithDiagnostics));
4433 Error(
"IsOfType",
"Record decl of type %s not found in the AST.", typ.c_str());
4438 const clang::CXXRecordDecl *mostRecentDecl = thisDecl->getMostRecentDecl();
4463 if (!IsStdClass(cl)) {
4464 auto *nsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext());
4465 if (cl.getName() !=
"RVec" || nsDecl ==
nullptr || nsDecl->getName() !=
"VecOps")
4468 auto *parentNsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext()->getParent());
4469 if (parentNsDecl ==
nullptr || parentNsDecl->getName() !=
"ROOT")
4473 return STLKind(cl.getName());
4477 using namespace clang;
4478 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4479 bool VisitTypedefType(
const TypedefType* TD) {
4482 bool VisitArrayType(
const ArrayType* AT) {
4483 return Visit(AT->getElementType().getTypePtr());
4485 bool VisitDecltypeType(
const DecltypeType* DT) {
4486 return Visit(DT->getUnderlyingType().getTypePtr());
4488 bool VisitPointerType(
const PointerType* PT) {
4489 return Visit(PT->getPointeeType().getTypePtr());
4491 bool VisitReferenceType(
const ReferenceType* RT) {
4492 return Visit(RT->getPointeeType().getTypePtr());
4494 bool VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType* STST) {
4495 return Visit(STST->getReplacementType().getTypePtr());
4497 bool VisitTemplateSpecializationType(
const TemplateSpecializationType* TST) {
4498 for (
int I = 0,
N = TST->getNumArgs();
I <
N; ++
I) {
4499 const TemplateArgument&
TA = TST->getArg(
I);
4500 if (
TA.getKind() == TemplateArgument::Type
4501 && Visit(
TA.getAsType().getTypePtr()))
4506 bool VisitTemplateTypeParmType(
const TemplateTypeParmType* TTPT) {
4509 bool VisitTypeOfType(
const TypeOfType* TOT) {
4510 return TOT->getUnderlyingType().getTypePtr();
4512 bool VisitElaboratedType(
const ElaboratedType* ET) {
4513 NestedNameSpecifier* NNS = ET->getQualifier();
4515 if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4516 if (Visit(NNS->getAsType()))
4519 NNS = NNS->getPrefix();
4521 return Visit(ET->getNamedType().getTypePtr());
4536 if (!instance)
return input;
4542 using namespace llvm;
4543 using namespace clang;
4544 const clang::ASTContext &Ctxt = instance->getAsCXXRecordDecl()->getASTContext();
4547 const clang::ElaboratedType* etype
4548 = llvm::dyn_cast<clang::ElaboratedType>(
input.getTypePtr());
4552 clang::Qualifiers scope_qualifiers =
input.getLocalQualifiers();
4553 assert(instance->getAsCXXRecordDecl() !=
nullptr &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4555 clang::NestedNameSpecifier *scope = ReSubstTemplateArgNNS(Ctxt,etype->getQualifier(),instance);
4556 clang::QualType subTy =
ReSubstTemplateArg(clang::QualType(etype->getNamedType().getTypePtr(),0),instance);
4558 if (scope) subTy = Ctxt.getElaboratedType(clang::ETK_None,scope,subTy);
4559 subTy = Ctxt.getQualifiedType(subTy,scope_qualifiers);
4563 QualType QT =
input;
4567 if (isa<clang::PointerType>(QT.getTypePtr())) {
4569 Qualifiers quals = QT.getQualifiers();
4572 if (nQT == QT->getPointeeType())
return QT;
4574 QT = Ctxt.getPointerType(nQT);
4576 QT = Ctxt.getQualifiedType(QT, quals);
4582 if (isa<ReferenceType>(QT.getTypePtr())) {
4584 bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
4585 Qualifiers quals = QT.getQualifiers();
4588 if (nQT == QT->getPointeeType())
return QT;
4592 QT = Ctxt.getLValueReferenceType(nQT);
4594 QT = Ctxt.getRValueReferenceType(nQT);
4596 QT = Ctxt.getQualifiedType(QT, quals);
4602 if (isa<clang::ArrayType>(QT.getTypePtr())) {
4604 Qualifiers quals = QT.getQualifiers();
4606 if (
const auto arr = dyn_cast<ConstantArrayType>(QT.getTypePtr())) {
4609 if (newQT == arr->getElementType())
return QT;
4610 QT = Ctxt.getConstantArrayType(newQT,
4613 arr->getSizeModifier(),
4614 arr->getIndexTypeCVRQualifiers());
4616 }
else if (
const auto arr = dyn_cast<DependentSizedArrayType>(QT.getTypePtr())) {
4619 if (newQT == QT)
return QT;
4620 QT = Ctxt.getDependentSizedArrayType (newQT,
4622 arr->getSizeModifier(),
4623 arr->getIndexTypeCVRQualifiers(),
4624 arr->getBracketsRange());
4626 }
else if (
const auto arr = dyn_cast<IncompleteArrayType>(QT.getTypePtr())) {
4629 if (newQT == arr->getElementType())
return QT;
4630 QT = Ctxt.getIncompleteArrayType (newQT,
4631 arr->getSizeModifier(),
4632 arr->getIndexTypeCVRQualifiers());
4634 }
else if (
const auto arr = dyn_cast<VariableArrayType>(QT.getTypePtr())) {
4637 if (newQT == arr->getElementType())
return QT;
4638 QT = Ctxt.getVariableArrayType (newQT,
4640 arr->getSizeModifier(),
4641 arr->getIndexTypeCVRQualifiers(),
4642 arr->getBracketsRange());
4646 QT = Ctxt.getQualifiedType(QT, quals);
4651 etype = llvm::dyn_cast<clang::ElaboratedType>(instance);
4653 instance = etype->getNamedType().getTypePtr();
4654 if (!instance)
return input;
4657 const clang::TemplateSpecializationType* TST
4658 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instance);
4660 if (!TST)
return input;
4662 const clang::ClassTemplateSpecializationDecl* TSTdecl
4663 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instance->getAsCXXRecordDecl());
4665 if (!TSTdecl)
return input;
4667 const clang::SubstTemplateTypeParmType *substType
4668 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(
input.getTypePtr());
4672 const clang::ClassTemplateDecl *replacedCtxt =
nullptr;
4674 const clang::DeclContext *replacedDeclCtxt = substType->getReplacedParameter()->getDecl()->getDeclContext();
4675 const clang::CXXRecordDecl *decl = llvm::dyn_cast<clang::CXXRecordDecl>(replacedDeclCtxt);
4676 unsigned int index = substType->getReplacedParameter()->getIndex();
4679 if (decl->getKind() == clang::Decl::ClassTemplatePartialSpecialization) {
4680 const clang::ClassTemplatePartialSpecializationDecl *spec = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(decl);
4682 unsigned int depth = substType->getReplacedParameter()->getDepth();
4684 const TemplateArgument *instanceArgs = spec->getTemplateArgs().data();
4685 unsigned int instanceNArgs = spec->getTemplateArgs().size();
4689 for(
unsigned int A = 0; A < instanceNArgs; ++A) {
4690 if (instanceArgs[A].getKind() == clang::TemplateArgument::Type) {
4691 clang::QualType argQualType = instanceArgs[A].getAsType();
4693 const clang::TemplateTypeParmType *replacementType;
4695 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(argQualType);
4697 if (!replacementType) {
4698 const clang::SubstTemplateTypeParmType *argType
4699 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(argQualType);
4701 clang::QualType replacementQT = argType->getReplacementType();
4702 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(replacementQT);
4705 if (replacementType &&
4706 depth == replacementType->getDepth() &&
4707 index == replacementType->getIndex() )
4714 replacedCtxt = spec->getSpecializedTemplate();
4716 replacedCtxt = decl->getDescribedClassTemplate();
4718 }
else if (
auto const declguide = llvm::dyn_cast<clang::CXXDeductionGuideDecl>(replacedDeclCtxt)) {
4719 replacedCtxt = llvm::dyn_cast<clang::ClassTemplateDecl>(declguide->getDeducedTemplate());
4720 }
else if (
auto const ctdecl = llvm::dyn_cast<clang::ClassTemplateDecl>(replacedDeclCtxt)) {
4721 replacedCtxt = ctdecl;
4723 std::string astDump;
4724 llvm::raw_string_ostream ostream(astDump);
4725 instance->dump(ostream, Ctxt);
4727 ROOT::TMetaUtils::Warning(
"ReSubstTemplateArg",
"Unexpected type of declaration context for template parameter: %s.\n\tThe responsible class is:\n\t%s\n",
4728 replacedDeclCtxt->getDeclKindName(), astDump.c_str());
4729 replacedCtxt =
nullptr;
4732 if ((replacedCtxt && replacedCtxt->getCanonicalDecl() == TSTdecl->getSpecializedTemplate()->getCanonicalDecl())
4734 substType->getReplacedParameter()->getDecl()
4735 == TSTdecl->getSpecializedTemplate ()->getTemplateParameters()->getParam(
index))
4737 if (
index >= TST->getNumArgs() ) {
4743 }
else if (TST->getArg(
index).getKind() == clang::TemplateArgument::Type) {
4744 return TST->getArg(
index).getAsType();
4753 const clang::TemplateSpecializationType* inputTST
4754 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
input.getTypePtr());
4755 const clang::ASTContext& astCtxt = TSTdecl->getASTContext();
4758 bool mightHaveChanged =
false;
4759 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
4760 for(clang::TemplateSpecializationType::iterator
I = inputTST->begin(), E = inputTST->end();
4762 if (
I->getKind() != clang::TemplateArgument::Type) {
4763 desArgs.push_back(*
I);
4767 clang::QualType SubTy =
I->getAsType();
4769 if (llvm::isa<clang::SubstTemplateTypeParmType>(SubTy)
4770 || llvm::isa<clang::TemplateSpecializationType>(SubTy)) {
4772 mightHaveChanged = SubTy != newSubTy;
4773 if (!newSubTy.isNull()) {
4774 desArgs.push_back(clang::TemplateArgument(newSubTy));
4777 desArgs.push_back(*
I);
4781 if (mightHaveChanged) {
4782 clang::Qualifiers qualifiers =
input.getLocalQualifiers();
4783 input = astCtxt.getTemplateSpecializationType(inputTST->getTemplateName(),
4785 inputTST->getCanonicalTypeInternal());
4786 input = astCtxt.getQualifiedType(
input, qualifiers);
4798 if ( nArgsToRemove == 0 ||
name ==
"")
4805 unsigned int nArgsRemoved=0;
4806 unsigned int nBraces=0;
4808 while (nArgsRemoved!=nArgsToRemove && cur<
length){
4810 if (
c ==
'<') nBraces++;
4811 if (
c ==
'>') nBraces--;
4812 if (
c ==
',' && nBraces==1 ) nArgsRemoved++;
4826 static const char *stls[] =
4827 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
4828 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
"RVec",
nullptr};
4842 for(
int k=1;stls[k];k++) {
if (
type.equals(stls[k]))
return values[k];}
4853 TND = TND->getMostRecentDecl();
4854 while (TND && !(TND->hasAttrs()))
4855 TND = TND->getPreviousDecl();
4867 TD = TD->getMostRecentDecl();
4868 while (TD && !(TD->hasAttrs() && TD->isThisDeclarationADefinition()))
4869 TD = TD->getPreviousDecl();
4878 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4880 const clang::DeclContext* enclosingNamespaceDeclCtxt = decl.getDeclContext();
4881 if (!enclosingNamespaceDeclCtxt)
return;
4883 const clang::NamespaceDecl* enclosingNamespace =
4884 clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4885 if (!enclosingNamespace)
return;
4887 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4888 enclosingNamespace->isInline()));
4898 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4900 const clang::DeclContext* enclosingNamespaceDeclCtxt = ctxt.getParent ();
4903 if (!enclosingNamespaceDeclCtxt) {
4909 const clang::NamespaceDecl* enclosingNamespace = clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4910 if (!enclosingNamespace)
return;
4913 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4914 enclosingNamespace->isInline()));
4925 std::list<std::pair<std::string,unsigned int> >& enclosingSc)
4927 const clang::DeclContext* enclosingDeclCtxt = decl.getDeclContext();
4928 if (!enclosingDeclCtxt)
return nullptr;
4930 unsigned int scopeType;
4932 if (
auto enclosingNamespacePtr =
4933 clang::dyn_cast<clang::NamespaceDecl>(enclosingDeclCtxt)){
4934 scopeType= enclosingNamespacePtr->isInline() ? 1 : 0;
4935 enclosingSc.push_back(std::make_pair(enclosingNamespacePtr->getNameAsString(),scopeType));
4939 if (
auto enclosingClassPtr =
4940 clang::dyn_cast<clang::RecordDecl>(enclosingDeclCtxt)){
4941 return enclosingClassPtr;
4953 std::string::size_type beginVar = 0;
4954 std::string::size_type endVar = 0;
4955 while ((beginVar = txt.find(
'$', beginVar)) != std::string::npos
4956 && beginVar + 1 < txt.length()) {
4957 std::string::size_type beginVarName = beginVar + 1;
4958 std::string::size_type endVarName = std::string::npos;
4959 if (txt[beginVarName] ==
'(') {
4961 endVarName = txt.find(
')', beginVarName);
4963 if (endVarName == std::string::npos) {
4965 varname, txt.c_str() + beginVar);
4968 endVar = endVarName + 1;
4971 beginVarName = beginVar + 1;
4972 endVarName = beginVarName;
4973 while (isalnum(txt[endVarName]) || txt[endVarName] ==
'_')
4975 endVar = endVarName;
4978 const char* val = getenv(txt.substr(beginVarName,
4979 endVarName - beginVarName).c_str());
4982 txt.replace(beginVar, endVar - beginVar, val);
4983 int lenval = strlen(val);
4984 int delta = lenval - (endVar - beginVar);
4988 beginVar = endVar + 1;
5000 const char* envInclPath = getenv(
"ROOT_INCLUDE_PATH");
5004 std::istringstream envInclPathsStream(envInclPath);
5005 std::string inclPath;
5006 while (std::getline(envInclPathsStream, inclPath,
':')) {
5009 if (!inclPath.empty()) {
5010 clingArgs.push_back(
"-I");
5011 clingArgs.push_back(inclPath);
5022 size_t start_pos = 0;
5027 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
5028 str.replace(start_pos, from.length(), to);
5029 start_pos += to.length();
5030 if (recurse) changed =
true;
5046 if (theString.size() < theSubstring.size())
return false;
5047 const unsigned int theSubstringSize = theSubstring.size();
5048 return 0 == theString.compare(theString.size() - theSubstringSize,
5057 if (theString.size() < theSubstring.size())
return false;
5058 const unsigned int theSubstringSize = theSubstring.size();
5059 return 0 == theString.compare(0,
5077 size_t linkdeflen = 9;
5079 if (0 == strncasecmp(
filename + (
len - linkdeflen),
"linkdef", linkdeflen - 2)
5095 return llvm::sys::path::extension(
filename) ==
".h" ||
5096 llvm::sys::path::extension(
filename) ==
".hh" ||
5097 llvm::sys::path::extension(
filename) ==
".hpp" ||
5098 llvm::sys::path::extension(
filename) ==
".H" ||
5099 llvm::sys::path::extension(
filename) ==
".h++" ||
5100 llvm::sys::path::extension(
filename) ==
"hxx" ||
5101 llvm::sys::path::extension(
filename) ==
"Hxx" ||
5102 llvm::sys::path::extension(
filename) ==
"HXX";
5108 cling::Interpreter::IgnoreFilesFunc_t ignoreFiles,
5109 const cling::Interpreter &interp,
5112 clang::Sema &sema = interp.getSema();
5113 cling::Transaction theTransaction(sema);
5114 std::set<clang::Decl *> addedDecls;
5115 for (
auto decl : decls) {
5117 clang::Decl *ncDecl =
const_cast<clang::Decl *
>(decl);
5118 theTransaction.append(ncDecl);
5120 std::string newFwdDecl;
5121 llvm::raw_string_ostream llvmOstr(newFwdDecl);
5123 std::string locallogs;
5124 llvm::raw_string_ostream llvmLogStr(locallogs);
5125 interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr,
true,
5126 logs ? &llvmLogStr : nullptr, ignoreFiles);
5130 logs->swap(locallogs);
5142 std::string& defString)
5154 std::string& defString)
5156 std::list<std::pair<std::string,unsigned int> > enclosingNamespaces;
5159 if (rcdPtr)
return rcdPtr;
5162 static const std::string scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5164 std::string scopeName;
5165 std::string scopeContent;
5166 unsigned int scopeIndex;
5167 for (
auto const & encScope : enclosingNamespaces){
5168 scopeIndex = encScope.second;
5169 scopeName = encScope.first;
5170 scopeContent =
" { " + defString +
" }";
5171 defString = scopeType[scopeIndex] +
5193 const clang::TemplateParameterList& tmplParamList,
5194 const cling::Interpreter& interpreter)
5197 for (
auto prmIt = tmplParamList.begin();
5198 prmIt != tmplParamList.end(); prmIt++){
5200 if (prmIt != tmplParamList.begin())
5201 templateArgs +=
", ";
5203 auto nDecl = *prmIt;
5204 std::string typeName;
5207 if (llvm::isa<clang::TemplateTypeParmDecl>(nDecl)){
5208 typeName =
"typename ";
5209 if (nDecl->isParameterPack())
5211 typeName += (*prmIt)->getNameAsString();
5214 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(nDecl)){
5215 auto theType = nttpd->getType();
5218 if (theType.getAsString().find(
"enum") != std::string::npos){
5219 std::string astDump;
5220 llvm::raw_string_ostream ostream(astDump);
5221 nttpd->dump(ostream);
5223 ROOT::TMetaUtils::Warning(
nullptr,
"Forward declarations of templates with enums as template parameters. The responsible class is: %s\n", astDump.c_str());
5232 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(nDecl)){
5235 std::string astDump;
5236 llvm::raw_string_ostream ostream(astDump);
5237 ttpd->dump(ostream);
5239 ROOT::TMetaUtils::Error(
nullptr,
"Cannot reconstruct template template parameter forward declaration for %s\n", astDump.c_str());
5244 templateArgs += typeName;
5255 const cling::Interpreter& interpreter,
5256 std::string& defString)
5258 std::string templatePrefixString;
5259 auto tmplParamList= templDecl.getTemplateParameters();
5260 if (!tmplParamList){
5262 "Cannot extract template parameter list for %s",
5263 templDecl.getNameAsString().c_str());
5270 "Problems with arguments for forward declaration of class %s\n",
5271 templDecl.getNameAsString().c_str());
5274 templatePrefixString =
"template " + templatePrefixString +
" ";
5276 defString = templatePrefixString +
"class ";
5277 if (templDecl.isParameterPack())
5278 defString +=
"... ";
5279 defString += templDecl.getNameAsString();
5280 if (llvm::isa<clang::TemplateTemplateParmDecl>(&templDecl)) {
5294 std::string& argFwdDecl,
5295 const cling::Interpreter& interpreter,
5296 bool acceptStl=
false)
5302 if (clang::TemplateArgument::Type != arg.getKind())
return 0;
5304 auto argQualType = arg.getAsType();
5307 while (llvm::isa<clang::PointerType>(argQualType.getTypePtr())) argQualType = argQualType->getPointeeType();
5309 auto argTypePtr = argQualType.getTypePtr();
5312 if (llvm::isa<clang::EnumType>(argTypePtr)){
5317 if (llvm::isa<clang::BuiltinType>(argTypePtr)){
5322 if (
auto tdTypePtr = llvm::dyn_cast<clang::TypedefType>(argTypePtr)) {
5323 FwdDeclFromTypeDefNameDecl(*tdTypePtr->getDecl(), interpreter, argFwdDecl);
5327 if (
auto argRecTypePtr = llvm::dyn_cast<clang::RecordType>(argTypePtr)){
5329 if (
auto argRecDeclPtr = argRecTypePtr->getDecl()){
5330 FwdDeclFromRcdDecl(*argRecDeclPtr,interpreter,argFwdDecl,acceptStl);
5342 const cling::Interpreter& interpreter,
5343 std::string& defString,
5344 const std::string &normalizedName)
5348 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)) {
5349 if (
const auto *specDef = tmplSpecDeclPtr->getDefinition()) {
5350 if (specDef->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization)
5354 std::cout <<
" Forward declaring template spec " << normalizedName <<
":\n";
5355 for (
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()) {
5356 std::string argFwdDecl;
5359 std::cout <<
" o Template argument ";
5361 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5363 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5370 defString += argFwdDecl +
'\n';
5372 defString +=
"template <> class " + normalizedName +
';';
5386 const cling::Interpreter& interpreter,
5387 std::string& defString,
5395 if (!recordDecl.getIdentifier())
5399 std::string argsFwdDecl;
5401 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)){
5402 std::string argFwdDecl;
5404 std::cout <<
"Class " << recordDecl.getNameAsString()
5405 <<
" is a template specialisation. Treating its arguments.\n";
5406 for(
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()){
5409 std::cout <<
" o Template argument ";
5411 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5413 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5420 argsFwdDecl+=argFwdDecl;
5424 defString=argsFwdDecl;
5429 if (
auto tmplDeclPtr = tmplSpecDeclPtr->getSpecializedTemplate()){
5432 defString = argsFwdDecl +
"\n" + defString;
5437 defString =
"class " + recordDecl.getNameAsString() +
";";
5438 const clang::RecordDecl* rcd =
EncloseInScopes(recordDecl, defString);
5446 defString = argsFwdDecl +
"\n" + defString;
5457 const cling::Interpreter& interpreter,
5458 std::string& fwdDeclString,
5459 std::unordered_set<std::string>* fwdDeclSetPtr)
5461 std::string buffer = tdnDecl.getNameAsString();
5462 std::string underlyingName;
5463 auto underlyingType = tdnDecl.getUnderlyingType().getCanonicalType();
5464 if (
const clang::TagType* TT
5465 = llvm::dyn_cast<clang::TagType>(underlyingType.getTypePtr())) {
5466 if (clang::NamedDecl* ND = TT->getDecl()) {
5467 if (!ND->getIdentifier()) {
5481 if (underlyingName.find(
">::") != std::string::npos)
5484 buffer=
"typedef "+underlyingName+
" "+buffer+
";";
5496 auto& ctxt = tdnDecl.getASTContext();
5497 auto immediatelyUnderlyingType = underlyingType.getSingleStepDesugaredType(ctxt);
5499 if (
auto underlyingTdnTypePtr = llvm::dyn_cast<clang::TypedefType>(immediatelyUnderlyingType.getTypePtr())){
5500 std::string tdnFwdDecl;
5501 auto underlyingTdnDeclPtr = underlyingTdnTypePtr->getDecl();
5506 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(tdnFwdDecl).second)
5507 fwdDeclString+=tdnFwdDecl;
5508 }
else if (
auto CXXRcdDeclPtr = immediatelyUnderlyingType->getAsCXXRecordDecl()){
5509 std::string classFwdDecl;
5511 std::cout <<
"Typedef " << tdnDecl.getNameAsString() <<
" hides a class: "
5512 << CXXRcdDeclPtr->getNameAsString() << std::endl;
5521 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(classFwdDecl).second)
5522 fwdDeclString+=classFwdDecl;
5525 fwdDeclString+=buffer;
5537 std::string& valAsString,
5538 const clang::PrintingPolicy& ppolicy)
5540 auto defArgExprPtr = par.getDefaultArg();
5541 auto& ctxt = par.getASTContext();
5542 if(!defArgExprPtr->isEvaluatable(ctxt)){
5546 auto defArgType = par.getType();
5549 if (defArgType->isBooleanType()){
5551 defArgExprPtr->EvaluateAsBooleanCondition (
result,ctxt);
5552 valAsString=std::to_string(
result);
5557 if (defArgType->isIntegerType()){
5558 clang::Expr::EvalResult evalResult;
5559 defArgExprPtr->EvaluateAsInt(evalResult, ctxt);
5560 llvm::APSInt
result = evalResult.Val.getInt();
5561 auto uintVal = *
result.getRawData();
5562 if (
result.isNegative()){
5563 long long int intVal=uintVal*-1;
5564 valAsString=std::to_string(intVal);
5566 valAsString=std::to_string(uintVal);
5573 llvm::raw_string_ostream rso(valAsString);
5574 defArgExprPtr->printPretty(rso,
nullptr,ppolicy);
5575 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.