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"
56#include "cling/Interpreter/InterpreterAccessRAII.h"
58#include "llvm/Support/Path.h"
59#include "llvm/Support/FileSystem.h"
64#define strncasecmp _strnicmp
75 llvm::SmallString<256> result_path;
76 llvm::sys::fs::real_path(path, result_path,
true);
77 return result_path.str().str();
84 using DeclsCont_t = TNormalizedCtxt::Config_t::SkipCollection;
101 bool replace =
false);
111static clang::NestedNameSpecifier *AddDefaultParametersNNS(
const clang::ASTContext& Ctx,
112 clang::NestedNameSpecifier* scope,
113 const cling::Interpreter &interpreter,
115 if (!scope)
return nullptr;
117 const clang::Type* scope_type = scope->getAsType();
120 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
122 outer_scope = AddDefaultParametersNNS(Ctx, outer_scope, interpreter, normCtxt);
125 clang::QualType addDefault =
128 if (addDefault.getTypePtr() != scope_type)
129 return clang::NestedNameSpecifier::Create(Ctx,outer_scope,
131 addDefault.getTypePtr());
138static bool CheckDefinition(
const clang::CXXRecordDecl *cl,
const clang::CXXRecordDecl *context)
140 if (!cl->hasDefinition()) {
143 "Missing definition for class %s, please #include its header in the header of %s\n",
144 cl->getName().str().c_str(), context->getName().str().c_str());
147 "Missing definition for class %s\n",
148 cl->getName().str().c_str());
160static clang::NestedNameSpecifier *ReSubstTemplateArgNNS(
const clang::ASTContext &Ctxt,
161 clang::NestedNameSpecifier *scope,
164 if (!scope)
return nullptr;
166 const clang::Type* scope_type = scope->getAsType();
168 clang::NestedNameSpecifier* outer_scope = scope->getPrefix();
170 outer_scope = ReSubstTemplateArgNNS(Ctxt, outer_scope,
instance);
172 clang::QualType substScope =
175 scope = clang::NestedNameSpecifier::Create(Ctxt,outer_scope,
177 substScope.getTypePtr());
184static bool IsTypeInt(
const clang::Type *
type)
186 const clang::BuiltinType * builtin = llvm::dyn_cast<clang::BuiltinType>(
type->getCanonicalTypeInternal().getTypePtr());
188 return builtin->isInteger();
196static bool IsFieldDeclInt(
const clang::FieldDecl *field)
198 return IsTypeInt(field->getType().getTypePtr());
204static const clang::FieldDecl *GetDataMemberFromAll(
const clang::CXXRecordDecl &cl, llvm::StringRef
what)
206 clang::ASTContext &
C = cl.getASTContext();
207 clang::DeclarationName DName = &
C.Idents.get(
what);
208 auto R = cl.lookup(DName);
209 for (
const clang::NamedDecl *D :
R)
210 if (
auto FD = llvm::dyn_cast<const clang::FieldDecl>(D))
218static const clang::FieldDecl *GetDataMemberFromAllParents(clang::Sema &SemaR,
const clang::CXXRecordDecl &cl,
const char *
what)
220 clang::DeclarationName DName = &SemaR.Context.Idents.get(
what);
221 clang::LookupResult
R(SemaR, DName, clang::SourceLocation(),
222 clang::Sema::LookupOrdinaryName,
223 clang::Sema::ForExternalRedeclaration);
224 SemaR.LookupInSuper(
R, &
const_cast<clang::CXXRecordDecl&
>(cl));
227 return llvm::dyn_cast<const clang::FieldDecl>(
R.getFoundDecl());
231cling::LookupHelper::DiagSetting ToLHDS(
bool wantDiags) {
233 ? cling::LookupHelper::WithDiagnostics
234 : cling::LookupHelper::NoDiagnostics;
250 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
251 "Tring to specify a number of template arguments to keep for a null pointer. Exiting without assigning any value.\n");
255 const clang::ClassTemplateDecl* canTempl = templ->getCanonicalDecl();
259 const std::string templateName (canTempl->getNameAsString());
260 const std::string i_str (std::to_string(
i));
262 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
263 "Tring to specify for template %s %s arguments to keep, while before this number was %s\n",
264 canTempl->getNameAsString().c_str(),
266 previousArgsToKeep.c_str());
277 const clang::ClassTemplateDecl* constTempl = templ->getCanonicalDecl();
298 return fImpl->GetConfig();
301 return fImpl->GetTypeWithAlternative();
305 return fImpl->AddTemplAndNargsToKeep(templ,
i);
309 return fImpl->GetNargsToKeep(templ);
312 return fImpl->GetTemplNargsToKeepMap();
317 return fImpl->keepTypedef(lh,
name, replace);
321 const std::string &normalizedName)
325 if (normalizedName.find(
"Double32_t") != std::string::npos
326 || normalizedName.find(
"Float16_t") != std::string::npos)
328 std::unique_ptr<clang::MangleContext> mangleCtx(rDecl->getASTContext().createMangleContext());
329 std::string mangledName;
331 llvm::raw_string_ostream sstr(mangledName);
332 if (
const clang::TypeDecl* TD = llvm::dyn_cast<clang::TypeDecl>(rDecl)) {
333 mangleCtx->mangleCXXRTTI(clang::QualType(TD->getTypeForDecl(), 0), sstr);
336 if (!mangledName.empty()) {
339 if (mangledName[0] ==
'\01')
340 mangledName.erase(0, 1);
342 if (!errDemangle && demangledTIName) {
343 static const char typeinfoNameFor[] =
" `RTTI Type Descriptor'";
344 if (strstr(demangledTIName, typeinfoNameFor)) {
345 std::string demangledName = demangledTIName;
346 demangledName.erase(demangledName.end() - strlen(typeinfoNameFor), demangledName.end());
349 if (!errDemangle && demangledTIName) {
350 static const char typeinfoNameFor[] =
"typeinfo for ";
351 if (!strncmp(demangledTIName, typeinfoNameFor, strlen(typeinfoNameFor))) {
352 std::string demangledName = demangledTIName + strlen(typeinfoNameFor);
354 free(demangledTIName);
355 return demangledName;
359 "Demangled typeinfo name '%s' does not contain `RTTI Type Descriptor'\n",
363 "Demangled typeinfo name '%s' does not start with 'typeinfo for'\n",
368 free(demangledTIName);
379 const clang::RecordDecl *decl,
382 bool rRequestNoInputOperator,
383 bool rRequestOnlyTClass,
384 int rRequestedVersionNumber,
385 const cling::Interpreter &interpreter,
398 const clang::Type *requestedType,
399 const clang::RecordDecl *decl,
400 const char *requestName,
401 unsigned int nTemplateArgsToSkip,
404 bool rRequestNoInputOperator,
405 bool rRequestOnlyTClass,
406 int rRequestVersionNumber,
407 const cling::Interpreter &interpreter,
419 "Could not remove the requested template arguments.\n");
428 const clang::Type *requestedType,
429 const clang::RecordDecl *decl,
430 const char *requestName,
433 bool rRequestNoInputOperator,
434 bool rRequestOnlyTClass,
435 int rRequestVersionNumber,
436 const cling::Interpreter &interpreter,
453 const clang::RecordDecl *decl,
454 const char *requestName,
457 bool rRequestNoInputOperator,
458 bool rRequestOnlyTClass,
459 int rRequestVersionNumber,
460 const cling::Interpreter &interpreter,
471 if (requestName && requestName[0]) {
488 bool *shuttingDownPtr,
489 const int* pgDebug ):
505 if (tname.empty())
return false;
515 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
516 clang::QualType t = lh.findType(nameLong, ToLHDS(
WantDiags()));
518 clang::QualType
dest = cling::utils::Transform::GetPartiallyDesugaredType(
fInterpreter->getCI()->getASTContext(), t,
fNormalizedCtxt->GetConfig(),
true );
519 if (!
dest.isNull() && (
dest != t)) {
522 dest.getAsStringInternal(nameLong,
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
530 const std::string &nameLong)
535 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
536 clang::QualType t = lh.findType(nondef.c_str(), ToLHDS(
WantDiags()));
538 clang::QualType
dest = cling::utils::Transform::GetPartiallyDesugaredType(
fInterpreter->getCI()->getASTContext(), t,
fNormalizedCtxt->GetConfig(),
true );
539 if (!
dest.isNull() && (
dest != t) &&
540 nameLong == t.getAsString(
fInterpreter->getCI()->getASTContext().getPrintingPolicy()))
553 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
554 const clang::Decl *scope = lh.findScope(base.c_str(), ToLHDS(
WantDiags()),
nullptr);
561 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(scope);
562 isInlined = nsdecl && nsdecl->isInline();
574 if (tname.empty())
return false;
594 const cling::LookupHelper& lh =
fInterpreter->getLookupHelper();
595 clang::QualType t = lh.findType(tname.c_str(), ToLHDS(
WantDiags()));
606 clang::PrintingPolicy policy(
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
607 policy.SuppressTagKeyword =
true;
608 policy.SuppressScope =
true;
617 if (strncmp(
result.c_str(),
"const ", 6) == 0) {
620 if (dropstd && strncmp(
result.c_str()+
offset,
"std::", 5) == 0) {
623 for(
unsigned int i = 1;
i<
result.length(); ++
i) {
626 if (dropstd &&
result.compare(
i,5,
"std::",5) == 0) {
635 }
else if ( (
i+1) <
result.length() &&
673 clang::QualType toSkip = lh.findType(
name, cling::LookupHelper::WithDiagnostics);
674 if (
const clang::Type* T = toSkip.getTypePtr()) {
675 const clang::TypedefType *
tt = llvm::dyn_cast<clang::TypedefType>(T);
677 clang::Decl* D =
tt->getDecl();
680 clang::QualType canon = toSkip->getCanonicalTypeInternal();
681 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),T));
701 clang::QualType toSkip = lh.findType(
"string", cling::LookupHelper::WithDiagnostics);
702 if (!toSkip.isNull()) {
703 if (
const clang::TypedefType* TT
704 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
705 fConfig.m_toSkip.insert(TT->getDecl());
707 toSkip = lh.findType(
"std::string", cling::LookupHelper::WithDiagnostics);
708 if (!toSkip.isNull()) {
709 if (
const clang::TypedefType* TT
710 = llvm::dyn_cast_or_null<clang::TypedefType>(toSkip.getTypePtr()))
711 fConfig.m_toSkip.insert(TT->getDecl());
713 clang::QualType canon = toSkip->getCanonicalTypeInternal();
714 fConfig.m_toReplace.insert(std::make_pair(canon.getTypePtr(),toSkip.getTypePtr()));
725 return (cl.getKind() == clang::Decl::ClassTemplatePartialSpecialization
726 || cl.getKind() == clang::Decl::ClassTemplateSpecialization);
733 const cling::Interpreter& interp)
735 clang::Sema* S = &interp.getSema();
736 const clang::NamedDecl* ND = cling::utils::Lookup::Named(S,
name, cl);
737 if (ND == (clang::NamedDecl*)-1)
738 return (clang::FunctionDecl*)-1;
739 return llvm::dyn_cast_or_null<clang::FunctionDecl>(ND);
745const clang::CXXRecordDecl *
747 bool ,
const clang::Type** resultType)
749 const cling::LookupHelper& lh = interp.getLookupHelper();
752 const clang::CXXRecordDecl *
result
753 = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
754 (lh.findScope(
name, cling::LookupHelper::NoDiagnostics, resultType));
756 std::string std_name(
"std::");
760 result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
761 (lh.findScope(std_name, cling::LookupHelper::NoDiagnostics, resultType));
771 clang::QualType qType(cl->getTypeForDecl(),0);
779 clang::Sema& S = interp.getCI()->getSema();
782 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interp));
783 return S.RequireCompleteType(Loc, Type, clang::diag::err_incomplete_type);
789 const clang::CXXRecordDecl *context,
const cling::Interpreter &interp)
795 if (!cl->getDefinition() || !cl->isCompleteDefinition()) {
799 if (!CheckDefinition(cl, context) || !CheckDefinition(base, context)) {
803 if (!base->hasDefinition()) {
807 return cl->isDerivedFrom(base);
819 const clang::NamedDecl *base
823 return IsBase(CRD, llvm::dyn_cast<clang::CXXRecordDecl>( base ),
824 llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext()),interp);
832 const clang::NamedDecl &forcontext,
833 const clang::QualType &qti,
834 const char *R__t,
int rwmode,
835 const cling::Interpreter &interp,
838 static const clang::CXXRecordDecl *TObject_decl
841 kBIT_ISTOBJECT = 0x10000000,
842 kBIT_HASSTREAMER = 0x20000000,
843 kBIT_ISSTRING = 0x40000000,
845 kBIT_ISPOINTER = 0x00001000,
846 kBIT_ISFUNDAMENTAL = 0x00000020,
847 kBIT_ISENUM = 0x00000008
850 const clang::Type &ti( * qti.getTypePtr() );
860 clang::CXXRecordDecl *cxxtype = rawtype->getAsCXXRecordDecl() ;
862 int isTObj = cxxtype && (
IsBase(cxxtype,TObject_decl,
nullptr,interp) || rawname ==
"TObject");
866 if (ti.isPointerType()) kase |= kBIT_ISPOINTER;
867 if (rawtype->isFundamentalType()) kase |= kBIT_ISFUNDAMENTAL;
868 if (rawtype->isEnumeralType()) kase |= kBIT_ISENUM;
871 if (isTObj) kase |= kBIT_ISTOBJECT;
872 if (isStre) kase |= kBIT_HASSTREAMER;
873 if (tiName ==
"string") kase |= kBIT_ISSTRING;
874 if (tiName ==
"string*") kase |= kBIT_ISSTRING;
878 tcl =
" internal error in rootcling ";
883 if (R__t) finalString <<
" " << tiName <<
" " << R__t <<
";" << std::endl;
886 case kBIT_ISFUNDAMENTAL:
888 finalString <<
" R__b >> " << R__t <<
";" << std::endl;
891 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
893 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
902 finalString <<
" Int_t readtemp;" << std::endl
903 <<
" R__b >> readtemp;" << std::endl
904 <<
" " << R__t <<
" = static_cast<" << tiName <<
">(readtemp);" << std::endl;
907 case kBIT_HASSTREAMER:
908 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
910 finalString <<
" " << R__t <<
".Streamer(R__b);" << std::endl;
913 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
916 finalString <<
" if (R__b.GetInfo() && R__b.GetInfo()->GetOldVersion()<=3) {" << std::endl;
917 if (cxxtype && cxxtype->isAbstract()) {
918 finalString <<
" R__ASSERT(0);// " << objType <<
" is abstract. We assume that older file could not be produced using this streaming method." << std::endl;
920 finalString <<
" " << R__t <<
" = new " << objType <<
";" << std::endl
921 <<
" " << R__t <<
"->Streamer(R__b);" << std::endl;
923 finalString <<
" } else {" << std::endl
924 <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl
925 <<
" }" << std::endl;
930 finalString <<
" {TString R__str;" << std::endl
931 <<
" R__str.Streamer(R__b);" << std::endl
932 <<
" " << R__t <<
" = R__str.Data();}" << std::endl;
935 case kBIT_ISSTRING|kBIT_ISPOINTER:
937 finalString <<
" {TString R__str;" << std::endl
938 <<
" R__str.Streamer(R__b);" << std::endl
939 <<
" " << R__t <<
" = new string(R__str.Data());}" << std::endl;
944 finalString <<
" " << R__t <<
" = (" << tiName <<
")R__b.ReadObjectAny(" << tcl <<
");" << std::endl;
949 finalString <<
" R__b.StreamObject(&" << R__t <<
"," << tcl <<
");" << std::endl;
957 case kBIT_ISFUNDAMENTAL:
958 case kBIT_ISPOINTER|kBIT_ISTOBJECT|kBIT_HASSTREAMER:
960 finalString <<
" R__b << " << R__t <<
";" << std::endl;
965 finalString <<
" { void *ptr_enum = (void*)&" << R__t <<
";\n";
966 finalString <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_enum); }" << std::endl;
969 case kBIT_HASSTREAMER:
970 case kBIT_HASSTREAMER|kBIT_ISTOBJECT:
972 finalString <<
" ((" << objType <<
"&)" << R__t <<
").Streamer(R__b);" << std::endl;
975 case kBIT_HASSTREAMER|kBIT_ISPOINTER:
977 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
982 finalString <<
" {TString R__str(" << R__t <<
".c_str());" << std::endl
983 <<
" R__str.Streamer(R__b);};" << std::endl;
986 case kBIT_ISSTRING|kBIT_ISPOINTER:
988 finalString <<
" {TString R__str(" << R__t <<
"->c_str());" << std::endl
989 <<
" R__str.Streamer(R__b);}" << std::endl;
994 finalString <<
" R__b.WriteObjectAny(" << R__t <<
"," << tcl <<
");" << std::endl;
999 finalString <<
" R__b.StreamObject((" << objType <<
"*)&" << R__t <<
"," << tcl <<
");" << std::endl;
1011 clang::CXXRecordDecl* ncCl =
const_cast<clang::CXXRecordDecl*
>(cl);
1014 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
1016 if (
auto* Ctor = interpreter.getCI()->getSema().LookupDefaultConstructor(ncCl)) {
1017 if (Ctor->getAccess() == clang::AS_public && !Ctor->isDeleted()) {
1030 const char *typeOfArg,
1031 const clang::CXXRecordDecl *expectedArgType,
1032 const cling::Interpreter& interpreter)
1034 if (typeOfArg && !expectedArgType) {
1035 const cling::LookupHelper& lh = interpreter.getLookupHelper();
1038 clang::QualType instanceType = lh.findType(typeOfArg, cling::LookupHelper::WithDiagnostics);
1039 if (!instanceType.isNull())
1040 expectedArgType = instanceType->getAsCXXRecordDecl();
1043 if (!expectedArgType)
1047 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
1048 for (
auto iter = cl->ctor_begin(), end = cl->ctor_end(); iter != end; ++iter)
1050 if ((iter->getAccess() != clang::AS_public) || (iter->getNumParams() != 1))
1054 clang::QualType argType((*iter->param_begin())->getType());
1055 argType = argType.getDesugaredType(cl->getASTContext());
1058 if (argType->isPointerType()) {
1060 argType = argType->getPointeeType();
1061 }
else if (argType->isReferenceType()) {
1063 argType = argType.getNonReferenceType();
1067 argType = argType.getDesugaredType(cl->getASTContext());
1068 const clang::CXXRecordDecl *argDecl = argType->getAsCXXRecordDecl();
1070 if (argDecl->getCanonicalDecl() == expectedArgType->getCanonicalDecl()) {
1071 return ioCtorCategory;
1074 std::string realArg = argType.getAsString();
1075 std::string clarg(
"class ");
1077 if (realArg == clarg)
1078 return ioCtorCategory;
1091 const cling::Interpreter& interpreter)
1093 const char *arg = ioctortype.
GetName();
1095 if (!ioctortype.
GetType() && (!arg || !arg[0])) {
1108 const char *method,
const char *
proto,
1109 const cling::Interpreter &interp,
1112 const clang::FunctionDecl* funcD
1113 = interp.getLookupHelper().findFunctionProto(cinfo, method,
proto,
1114 diagnose ? cling::LookupHelper::WithDiagnostics
1115 : cling::LookupHelper::NoDiagnostics);
1117 return llvm::dyn_cast<const clang::CXXMethodDecl>(funcD);
1129 const cling::LookupHelper& lh = interp.getLookupHelper();
1132 clang::QualType instanceType = lh.findType(type_of_arg, cling::LookupHelper::WithDiagnostics);
1133 if (!instanceType.isNull())
1134 fArgType = instanceType->getAsCXXRecordDecl();
1148 const cling::Interpreter &interp)
1150 if (cl->isAbstract())
return false;
1152 for (
auto & ctorType : ctorTypes) {
1159 std::string
proto( ctorType.GetName() );
1160 bool defaultCtor =
proto.empty();
1172 arg +=
")nullptr )";
1175 const clang::CXXMethodDecl *method
1177 cling::LookupHelper::NoDiagnostics);
1178 if (method && method->getAccess() != clang::AS_public) {
1192 const cling::Interpreter& interp)
1194 if (!cl)
return false;
1196 if (cl->hasUserDeclaredDestructor()) {
1198 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
1199 clang::CXXDestructorDecl *
dest = cl->getDestructor();
1201 return (
dest->getAccess() == clang::AS_public);
1213 const char *methodname,
1215 const cling::Interpreter &interp,
1218 const clang::CXXMethodDecl *method
1220 diagnose ? cling::LookupHelper::WithDiagnostics
1221 : cling::LookupHelper::NoDiagnostics);
1222 return (method && method->getAccess() == clang::AS_public);
1233 const char *
proto =
"TDirectory*";
1234 const char *
name =
"DirectoryAutoAdd";
1248 const char *
proto =
"TCollection*,TFileMergeInfo*";
1249 const char *
name =
"Merge";
1262 const char *
proto =
"TCollection*";
1263 const char *
name =
"Merge";
1278 const char *
proto =
"TFileMergeInfo*";
1279 const char *
name =
"ResetAfterMerge";
1289 const clang::CXXRecordDecl* clxx,
1290 const cling::Interpreter &interp,
1293 static const char *
proto =
"TBuffer&";
1295 const clang::CXXMethodDecl *method
1297 cling::LookupHelper::NoDiagnostics);
1298 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1300 return (method && method->getDeclContext() == clxx_as_context
1308 const clang::CXXRecordDecl* clxx,
1309 const cling::Interpreter &interp,
1312 static const char *
proto =
"TBuffer&,TClass*";
1314 const clang::CXXMethodDecl *method
1316 cling::LookupHelper::NoDiagnostics);
1317 const clang::DeclContext *clxx_as_context = llvm::dyn_cast<clang::DeclContext>(clxx);
1319 return (method && method->getDeclContext() == clxx_as_context
1349 clang::QualType qualType(&
type,0);
1381 llvm::raw_string_ostream stream(qual_name);
1382 clang::PrintingPolicy policy( cl.getASTContext().getPrintingPolicy() );
1383 policy.SuppressTagKeyword =
true;
1384 policy.SuppressUnwrittenScope =
true;
1386 cl.getNameForDiagnostic(stream,policy,
true);
1389 if ( qual_name ==
"(anonymous " || qual_name ==
"(unnamed" ) {
1390 size_t pos = qual_name.find(
':');
1391 qual_name.erase(0,pos+2);
1407 const clang::Type* declType ( recordDecl.getTypeForDecl() );
1408 clang::QualType qualType(declType,0);
1442 std::stringstream dims;
1443 std::string typenameStr;
1445 const clang::ASTContext& astContext = cl.getASTContext();
1448 for(clang::RecordDecl::field_iterator field_iter = cl.field_begin(), end = cl.field_end();
1456 typenameStr.clear();
1460 clang::QualType fieldType(field_iter->getType());
1461 if (fieldType->isConstantArrayType()) {
1462 const clang::ConstantArrayType *arrayType = llvm::dyn_cast<clang::ConstantArrayType>(fieldType.getTypePtr());
1464 dims <<
"[" << arrayType->getSize().getLimitedValue() <<
"]";
1465 fieldType = arrayType->getElementType();
1466 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(arrayType->getArrayElementTypeNoTypeQual());
1476 for(clang::CXXRecordDecl::base_class_const_iterator iter = cl.bases_begin(), end = cl.bases_end();
1479 std::string basename( iter->getType()->getAsCXXRecordDecl()->getNameAsString() );
1489 const cling::Interpreter &interp,
1492 return interp.getLookupHelper().findFunctionProto(cinfo, method,
proto,
1493 diagnose ? cling::LookupHelper::WithDiagnostics
1494 : cling::LookupHelper::NoDiagnostics);
1528 clang::SourceLocation sourceLocation = decl->getLocation();
1529 clang::SourceManager& sourceManager = decl->getASTContext().getSourceManager();
1531 if (!sourceLocation.isValid() ) {
1535 if (!sourceLocation.isFileID()) {
1536 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
1539 if (sourceLocation.isValid() && sourceLocation.isFileID()) {
1540 return sourceManager.getLineNumber(sourceManager.getFileID(sourceLocation),sourceManager.getFileOffset(sourceLocation));
1553 while (llvm::isa<clang::PointerType>(instanceType.getTypePtr())
1554 || llvm::isa<clang::ReferenceType>(instanceType.getTypePtr()))
1556 instanceType = instanceType->getPointeeType();
1559 const clang::ElaboratedType* etype
1560 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
1562 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
1575 const clang::CXXRecordDecl* clxx = instanceType->getAsCXXRecordDecl();
1576 if (clxx && clxx->getTemplateSpecializationKind() != clang::TSK_Undeclared) {
1578 const clang::TemplateSpecializationType* TST
1579 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
1586 for (
const clang::TemplateArgument &
TA : TST->template_arguments()) {
1587 if (
TA.getKind() == clang::TemplateArgument::Type) {
1599 const cling::Interpreter &interp,
1602 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1603 if (!clxx || clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return false;
1605 clang::QualType instanceType = interp.getLookupHelper().findType(cl.
GetNormalizedName(),
1606 cling::LookupHelper::WithDiagnostics);
1607 if (instanceType.isNull()) {
1620 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(attribute);
1625 attrString = annAttr->getAnnotation().str();
1635 if (substrFound==std::string::npos) {
1640 attrName = attributeStr.substr(0, EndPart1);
1642 attrValue = attributeStr.substr(EndPart1 + separatorLength);
1650 std::string attrString;
1652 if (0!=ret)
return ret;
1660 const std::string& propName,
1661 std::string& propValue)
1663 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1664 attrIt!=decl.attr_end();++attrIt){
1665 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1666 if (!annAttr)
continue;
1668 llvm::StringRef attribute = annAttr->getAnnotation();
1669 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(
propNames::separator.c_str());
1670 if (split.first != propName.c_str())
continue;
1672 propValue = split.second.str();
1683 const std::string& propName,
1686 for (clang::Decl::attr_iterator attrIt = decl.attr_begin();
1687 attrIt!=decl.attr_end();++attrIt){
1688 clang::AnnotateAttr* annAttr = clang::dyn_cast<clang::AnnotateAttr>(*attrIt);
1689 if (!annAttr)
continue;
1691 llvm::StringRef attribute = annAttr->getAnnotation();
1692 std::pair<llvm::StringRef,llvm::StringRef> split = attribute.split(
propNames::separator.c_str());
1693 if (split.first != propName.c_str())
continue;
1695 return split.second.getAsInteger(10,propValue);
1706 const clang::CXXRecordDecl *decl,
1707 const cling::Interpreter &interp,
1710 bool& needCollectionProxy)
1714 std::string mappedname;
1716 std::string csymbol = classname;
1724 csymbol.insert(0,
"::");
1731 const cling::LookupHelper& lh = interp.getLookupHelper();
1734 bool isStdNotString = isStd && !isString;
1736 finalString <<
"namespace ROOT {" <<
"\n";
1740 finalString <<
" static TClass *" << mappedname.c_str() <<
"_Dictionary();\n"
1741 <<
" static void " << mappedname.c_str() <<
"_TClassManip(TClass*);\n";
1747 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p = nullptr);" <<
"\n";
1751 finalString <<
" static void *newArray_";
1752 finalString << mappedname.c_str();
1753 finalString <<
"(Long_t size, void *p);";
1754 finalString <<
"\n";
1759 finalString <<
" static void delete_" << mappedname.c_str() <<
"(void *p);" <<
"\n" <<
" static void deleteArray_" << mappedname.c_str() <<
"(void *p);" <<
"\n" <<
" static void destruct_" << mappedname.c_str() <<
"(void *p);" <<
"\n";
1762 finalString <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *obj, TDirectory *dir);" <<
"\n";
1765 finalString <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj);" <<
"\n";
1768 finalString <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass*);" <<
"\n";
1771 finalString <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj, TCollection *coll,TFileMergeInfo *info);" <<
"\n";
1774 finalString <<
" static void reset_" << mappedname.c_str() <<
"(void *obj, TFileMergeInfo *info);" <<
"\n";
1781 ROOT::SchemaRuleClassMap_t::iterator rulesIt1 =
ROOT::gReadRules.find( classname.c_str() );
1782 ROOT::SchemaRuleClassMap_t::iterator rulesIt2 =
ROOT::gReadRawRules.find( classname.c_str() );
1793 finalString <<
"\n // Schema evolution read functions\n";
1794 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt1->second.begin();
1795 while( rIt != rulesIt1->second.end() ) {
1801 std::string error_string;
1803 Warning(
nullptr,
"%s", error_string.c_str());
1804 rIt = rulesIt1->second.erase(rIt);
1812 if( rIt->find(
"code" ) != rIt->end() ) {
1828 finalString <<
"\n // Schema evolution read raw functions\n";
1829 std::list<ROOT::SchemaRuleMap_t>::iterator rIt = rulesIt2->second.begin();
1830 while( rIt != rulesIt2->second.end() ) {
1836 std::string error_string;
1838 Warning(
nullptr,
"%s", error_string.c_str());
1839 rIt = rulesIt2->second.erase(rIt);
1847 if( rIt->find(
"code" ) == rIt->end() )
1855 finalString <<
"\n" <<
" // Function generating the singleton type initializer" <<
"\n";
1857 finalString <<
" static TGenericClassInfo *GenerateInitInstanceLocal(const " << csymbol <<
"*)" <<
"\n" <<
" {" <<
"\n";
1859 finalString <<
" " << csymbol <<
" *ptr = nullptr;" <<
"\n";
1863 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< " << csymbol <<
" >(nullptr);" <<
"\n";
1866 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" << csymbol <<
"));" <<
"\n";
1868 finalString <<
" static ::ROOT::TGenericClassInfo " <<
"\n" <<
" instance(\"" << classname.c_str() <<
"\", ";
1871 finalString << csymbol <<
"::Class_Version(), ";
1873 finalString <<
"2, ";
1875 finalString <<
"-2, ";
1881 static const char *versionFunc =
"GetClassVersion";
1885 std::string
proto = classname +
"*";
1886 const clang::Decl* ctxt = llvm::dyn_cast<clang::Decl>((*cl).getDeclContext());
1887 const clang::FunctionDecl *methodinfo
1889 interp, cling::LookupHelper::NoDiagnostics);
1897 finalString <<
"GetClassVersion< ";
1898 finalString << classname.c_str();
1899 finalString <<
" >(), ";
1908 for (
unsigned int i=0;
i<
filename.length();
i++) {
1913 <<
"," <<
"\n" <<
" typeid(" << csymbol
1914 <<
"), ::ROOT::Internal::DefineBehavior(ptr, ptr)," <<
"\n" <<
" ";
1917 finalString <<
"&" << csymbol <<
"::Dictionary, ";
1919 finalString <<
"&" << mappedname <<
"_Dictionary, ";
1923 TClassTable__kHasCustomStreamerMember = 0x10
1928 rootflag = rootflag | TClassTable__kHasCustomStreamerMember;
1930 finalString <<
"isa_proxy, " << rootflag <<
"," <<
"\n" <<
" sizeof(" << csymbol <<
") );" <<
"\n";
1932 finalString <<
" instance.SetNew(&new_" << mappedname.c_str() <<
");" <<
"\n";
1934 finalString <<
" instance.SetNewArray(&newArray_" << mappedname.c_str() <<
");" <<
"\n";
1937 finalString <<
" instance.SetDelete(&delete_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDeleteArray(&deleteArray_" << mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDestructor(&destruct_" << mappedname.c_str() <<
");" <<
"\n";
1940 finalString <<
" instance.SetDirectoryAutoAdd(&directoryAutoAdd_" << mappedname.c_str() <<
");" <<
"\n";
1944 finalString <<
" instance.SetStreamerFunc(&streamer_" << mappedname.c_str() <<
");" <<
"\n";
1948 finalString <<
" instance.SetConvStreamerFunc(&conv_streamer_" << mappedname.c_str() <<
");" <<
"\n";
1951 finalString <<
" instance.SetMerge(&merge_" << mappedname.c_str() <<
");" <<
"\n";
1954 finalString <<
" instance.SetResetAfterMerge(&reset_" << mappedname.c_str() <<
");" <<
"\n";
1957 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
"Pushback" <<
"<Internal::TStdBitsetHelper< " << classname.c_str() <<
" > >()));" <<
"\n";
1959 needCollectionProxy =
true;
1960 }
else if (stl != 0 &&
1963 int idx = classname.find(
"<");
1965 const char* methodTCP =
nullptr;
1971 methodTCP=
"Pushback";
1974 methodTCP=
"Pushfront";
1980 methodTCP=
"MapInsert";
1992 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" << methodTCP <<
"< " << classNameForIO.c_str() <<
" >()));" <<
"\n";
1994 needCollectionProxy =
true;
2002 finalString <<
"\n" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2009 finalString <<
"\n" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2019 finalString <<
"\n" <<
" ::ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
2023 finalString <<
"\n" <<
" // the io read rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrules(" << rulesIt1->second.size() <<
");" <<
"\n";
2025 finalString <<
" instance.SetReadRules( readrules );" <<
"\n";
2029 finalString <<
"\n" <<
" // the io read raw rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrawrules(" << rulesIt2->second.size() <<
");" <<
"\n";
2031 finalString <<
" instance.SetReadRawRules( readrawrules );" <<
"\n";
2034 finalString <<
" return &instance;" <<
"\n" <<
" }" <<
"\n";
2038 finalString <<
" TGenericClassInfo *GenerateInitInstance(const " << csymbol <<
"*)" <<
"\n" <<
" {\n return GenerateInitInstanceLocal(static_cast<" << csymbol <<
"*>(nullptr));\n }" <<
"\n";
2041 finalString <<
" // Static variable to force the class initialization" <<
"\n";
2045 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstanceLocal(static_cast<const " << csymbol <<
"*>(nullptr)); R__UseDummy(_R__UNIQUE_DICT_(Init));" <<
"\n";
2048 finalString <<
"\n" <<
" // Dictionary for non-ClassDef classes" <<
"\n"
2049 <<
" static TClass *" << mappedname <<
"_Dictionary() {\n"
2050 <<
" TClass* theClass ="
2051 <<
"::ROOT::GenerateInitInstanceLocal(static_cast<const " << csymbol <<
"*>(nullptr))->GetClass();\n"
2052 <<
" " << mappedname <<
"_TClassManip(theClass);\n";
2053 finalString <<
" return theClass;\n";
2054 finalString <<
" }\n\n";
2058 std::string manipString;
2059 std::string attribute_s;
2060 std::string attrName, attrValue;
2062 bool attrMapExtracted =
false;
2063 if (decl->hasAttrs()){
2065 for (clang::Decl::attr_iterator attrIt = decl->attr_begin();
2066 attrIt!=decl->attr_end();++attrIt){
2073 if (attrName ==
"name" ||
2074 attrName ==
"pattern" ||
2075 attrName ==
"rootmap")
continue;
2081 if (!attrMapExtracted){
2082 manipString+=
" theClass->CreateAttributeMap();\n";
2083 manipString+=
" TDictAttributeMap* attrMap( theClass->GetAttributeMap() );\n";
2084 attrMapExtracted=
true;
2086 manipString+=
" attrMap->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2092 for(clang::CXXRecordDecl::decl_iterator internalDeclIt = decl->decls_begin();
2093 internalDeclIt != decl->decls_end(); ++internalDeclIt){
2094 if (!(!(*internalDeclIt)->isImplicit()
2095 && (clang::isa<clang::FieldDecl>(*internalDeclIt) ||
2096 clang::isa<clang::VarDecl>(*internalDeclIt))))
continue;
2099 if (!internalDeclIt->hasAttrs())
continue;
2101 attrMapExtracted =
false;
2102 bool memberPtrCreated =
false;
2104 for (clang::Decl::attr_iterator attrIt = internalDeclIt->attr_begin();
2105 attrIt!=internalDeclIt->attr_end();++attrIt){
2113 clang::NamedDecl* namedInternalDecl = clang::dyn_cast<clang::NamedDecl> (*internalDeclIt);
2114 if (!namedInternalDecl) {
2115 TMetaUtils::Error(
nullptr,
"Cannot convert field declaration to clang::NamedDecl");
2118 const std::string memberName(namedInternalDecl->getName());
2119 const std::string cppMemberName =
"theMember_"+memberName;
2122 const std::string dataMemberCreation=
" TDataMember* "+cppMemberName+
" = theClass->GetDataMember(\""+memberName+
"\");\n";
2135 if (!memberPtrCreated){
2136 manipString+=dataMemberCreation;
2137 memberPtrCreated=
true;
2140 if (!attrMapExtracted){
2141 manipString+=
" "+cppMemberName+
"->CreateAttributeMap();\n";
2142 manipString+=
" TDictAttributeMap* memberAttrMap_"+memberName+
"( theMember_"+memberName+
"->GetAttributeMap() );\n";
2143 attrMapExtracted=
true;
2146 manipString+=
" memberAttrMap_"+memberName+
"->AddProperty(\""+attrName +
"\",\""+attrValue+
"\");\n";
2153 finalString <<
" static void " << mappedname <<
"_TClassManip(TClass* " << (manipString.empty() ?
"":
"theClass") <<
"){\n"
2158 finalString <<
"} // end of namespace ROOT" <<
"\n" <<
"\n";
2168 std::string &clsname,
2169 std::string &nsname,
2170 const clang::CXXRecordDecl *cl)
2180 auto ctxt = cl->getEnclosingNamespaceContext();
2181 while(ctxt && ctxt!=cl && ctxt->isInlineNamespace()) {
2182 ctxt = ctxt->getParent();
2185 const clang::NamedDecl *namedCtxt = llvm::dyn_cast<clang::NamedDecl>(ctxt);
2186 if (namedCtxt && namedCtxt!=cl) {
2187 const clang::NamespaceDecl *nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(namedCtxt);
2188 if (nsdecl && !nsdecl->isAnonymousNamespace()) {
2190 clsname.erase (0, nsname.size() + 2);
2202 const clang::DeclContext *ctxt = cl.getDeclContext();
2203 while(ctxt && !ctxt->isNamespace()) {
2204 ctxt = ctxt->getParent();
2218 int closing_brackets = 0;
2222 if (ctxt && ctxt->isNamespace()) {
2224 const clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(ctxt);
2230 out <<
"namespace " << ns->getNameAsString() <<
" {" << std::endl;
2235 return closing_brackets;
2249 clang::TemplateSpecializationKind kind = cl->getTemplateSpecializationKind();
2250 if (kind == clang::TSK_Undeclared ) {
2253 }
else if (kind == clang::TSK_ExplicitSpecialization) {
2267 const char *
name = which;
2268 const char *
proto =
"size_t";
2269 const char *protoPlacement =
"size_t,void*";
2272 const clang::FunctionDecl *operatornew
2275 cling::LookupHelper::NoDiagnostics);
2276 const clang::FunctionDecl *operatornewPlacement
2278 name, protoPlacement, interp,
2279 cling::LookupHelper::NoDiagnostics);
2281 const clang::DeclContext *ctxtnew =
nullptr;
2282 const clang::DeclContext *ctxtnewPlacement =
nullptr;
2285 ctxtnew = operatornew->getParent();
2287 if (operatornewPlacement) {
2288 ctxtnewPlacement = operatornewPlacement->getParent();
2294 operatornewPlacement
2299 ctxtnew = operatornew->getParent();
2301 if (operatornewPlacement) {
2302 ctxtnewPlacement = operatornewPlacement->getParent();
2305 if (!ctxtnewPlacement) {
2313 if (ctxtnew == ctxtnewPlacement) {
2317 const clang::CXXRecordDecl* clnew = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnew);
2318 const clang::CXXRecordDecl* clnewPlacement = llvm::dyn_cast<clang::CXXRecordDecl>(ctxtnewPlacement);
2319 if (!clnew && !clnewPlacement) {
2325 if (clnew && !clnewPlacement) {
2329 if (!clnew && clnewPlacement) {
2334 if (clnew->isDerivedFrom(clnewPlacement)) {
2364 const clang::CXXRecordDecl *decl,
2365 const cling::Interpreter &interp,
2371 std::string mappedname;
2389 classname.insert(0,
"::");
2392 finalString <<
"namespace ROOT {" <<
"\n";
2397 finalString <<
" // Wrappers around operator new" <<
"\n";
2398 finalString <<
" static void *new_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" return p ? ";
2400 finalString <<
"new(p) ";
2401 finalString << classname.c_str();
2402 finalString << args;
2403 finalString <<
" : ";
2405 finalString <<
"::new(static_cast<::ROOT::Internal::TOperatorNewHelper*>(p)) ";
2406 finalString << classname.c_str();
2407 finalString << args;
2408 finalString <<
" : ";
2410 finalString <<
"new " << classname.c_str() << args <<
";" <<
"\n";
2411 finalString <<
" }" <<
"\n";
2415 finalString <<
" static void *newArray_";
2416 finalString << mappedname.c_str();
2417 finalString <<
"(Long_t nElements, void *p) {";
2418 finalString <<
"\n";
2419 finalString <<
" return p ? ";
2421 finalString <<
"new(p) ";
2422 finalString << classname.c_str();
2423 finalString <<
"[nElements] : ";
2425 finalString <<
"::new(static_cast<::ROOT::Internal::TOperatorNewHelper*>(p)) ";
2426 finalString << classname.c_str();
2427 finalString <<
"[nElements] : ";
2429 finalString <<
"new ";
2430 finalString << classname.c_str();
2431 finalString <<
"[nElements];";
2432 finalString <<
"\n";
2433 finalString <<
" }";
2434 finalString <<
"\n";
2439 finalString <<
" // Wrapper around operator delete" <<
"\n" <<
" static void delete_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" delete (static_cast<" << classname.c_str() <<
"*>(p));" <<
"\n" <<
" }" <<
"\n" <<
" static void deleteArray_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" delete [] (static_cast<" << classname.c_str() <<
"*>(p));" <<
"\n" <<
" }" <<
"\n" <<
" static void destruct_" << mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" typedef " << classname.c_str() <<
" current_t;" <<
"\n" <<
" (static_cast<current_t*>(p))->~current_t();" <<
"\n" <<
" }" <<
"\n";
2443 finalString <<
" // Wrapper around the directory auto add." <<
"\n" <<
" static void directoryAutoAdd_" << mappedname.c_str() <<
"(void *p, TDirectory *dir) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)p)->DirectoryAutoAdd(dir);" <<
"\n" <<
" }" <<
"\n";
2447 finalString <<
" // Wrapper around a custom streamer member function." <<
"\n" <<
" static void streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)obj)->" << classname.c_str() <<
"::Streamer(buf);" <<
"\n" <<
" }" <<
"\n";
2451 finalString <<
" // Wrapper around a custom streamer member function." <<
"\n" <<
" static void conv_streamer_" << mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass *onfile_class) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)obj)->" << classname.c_str() <<
"::Streamer(buf,onfile_class);" <<
"\n" <<
" }" <<
"\n";
2455 finalString <<
" // Wrapper around the merge function." <<
"\n" <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj,TCollection *coll,TFileMergeInfo *info) {" <<
"\n" <<
" return ((" << classname.c_str() <<
"*)obj)->Merge(coll,info);" <<
"\n" <<
" }" <<
"\n";
2457 finalString <<
" // Wrapper around the merge function." <<
"\n" <<
" static Long64_t merge_" << mappedname.c_str() <<
"(void *obj,TCollection *coll,TFileMergeInfo *) {" <<
"\n" <<
" return ((" << classname.c_str() <<
"*)obj)->Merge(coll);" <<
"\n" <<
" }" <<
"\n";
2461 finalString <<
" // Wrapper around the Reset function." <<
"\n" <<
" static void reset_" << mappedname.c_str() <<
"(void *obj,TFileMergeInfo *info) {" <<
"\n" <<
" ((" << classname.c_str() <<
"*)obj)->ResetAfterMerge(info);" <<
"\n" <<
" }" <<
"\n";
2463 finalString <<
"} // end of namespace ROOT for class " << classname.c_str() <<
"\n" <<
"\n";
2470 const cling::Interpreter &interp,
2477 if (version == 0)
return;
2481 const clang::CXXRecordDecl *clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2485 for(clang::CXXRecordDecl::base_class_const_iterator iter = clxx->bases_begin(), end = clxx->bases_end();
2496 for(clang::RecordDecl::field_iterator field_iter = clxx->field_begin(), end = clxx->field_end();
2500 std::string mTypename;
2506 if (!strcmp(shortTypeName,
"string")) {
2528 const clang::Type *rawtype =
m.getType()->getCanonicalTypeInternal().getTypePtr();
2529 if (rawtype->isArrayType()) {
2530 rawtype = rawtype->getBaseElementTypeUnsafe ();
2544 const clang::CXXRecordDecl* CRD = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
2553 if (!funcCV)
return -1;
2556 if (funcCV == (clang::FunctionDecl*)-1)
return 1;
2571 using res_t = std::pair<bool, int>;
2573 const clang::CompoundStmt* FuncBody
2574 = llvm::dyn_cast_or_null<clang::CompoundStmt>(funcCV->getBody());
2576 return res_t{
false, -1};
2577 if (FuncBody->size() != 1) {
2581 return res_t{
false, -1};
2583 const clang::ReturnStmt* RetStmt
2584 = llvm::dyn_cast<clang::ReturnStmt>(FuncBody->body_back());
2586 return res_t{
false, -1};
2587 const clang::Expr* RetExpr = RetStmt->getRetValue();
2593 if (
auto RetRes = RetExpr->getIntegerConstantExpr(funcCV->getASTContext())) {
2594 if (RetRes->isSigned())
2595 return res_t{
true, (
Version_t)RetRes->getSExtValue()};
2596 return res_t{
true, (
Version_t)RetRes->getZExtValue()};
2598 return res_t{
false, -1};
2614 clang::QualType
type =
m.getType();
2626 clang::QualType
type = base.getType();
2639 const std::function<
void(
const clang::Module::Header &)> &closure,
2640 bool includeDirectlyUsedModules)
2649 const std::size_t publicHeaderIndex = 4;
2652 const std::size_t maxArrayLength = ((
sizeof module.Headers) / (sizeof *module.Headers));
2653 static_assert(publicHeaderIndex + 1 == maxArrayLength,
2654 "'Headers' has changed it's size, we need to update publicHeaderIndex");
2659 llvm::SetVector<const clang::Module *> modules;
2660 modules.insert(&module);
2661 for (
size_t i = 0;
i < modules.size(); ++
i) {
2662 const clang::Module *M = modules[
i];
2663 for (
const clang::Module *subModule : M->submodules())
2664 modules.insert(subModule);
2667 for (
const clang::Module *
m : modules) {
2668 if (includeDirectlyUsedModules) {
2669 for (clang::Module *used :
m->DirectUses) {
2674 for (std::size_t
i = 0;
i < publicHeaderIndex;
i++) {
2675 auto &headerList =
m->Headers[
i];
2676 for (
const clang::Module::Header &moduleHeader : headerList) {
2677 closure(moduleHeader);
2691 static char t[4096];
2692 static const char* constwd =
"const ";
2693 static const char* constwdend =
"const";
2698 for (s=typeDesc;*s;s++) {
2701 if (lev==0 && *s==
'*')
continue;
2702 if (lev==0 && (strncmp(constwd,s,strlen(constwd))==0
2703 ||strcmp(constwdend,s)==0 ) ) {
2704 s+=strlen(constwd)-1;
2707 if (lev==0 && *s==
' ' && *(s+1)!=
'*') { p = t;
continue;}
2708 if (p - t > (
long)
sizeof(t)) {
2709 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2722 const cling::Interpreter& interp)
2727 if (!comment.empty() && comment[0] ==
'!')
2730 clang::QualType
type =
m.getType();
2732 if (
type->isReferenceType()) {
2737 std::string mTypeName =
type.getAsString(
m.getASTContext().getPrintingPolicy());
2738 if (!strcmp(mTypeName.c_str(),
"string") || !strcmp(mTypeName.c_str(),
"string*")) {
2741 if (!strcmp(mTypeName.c_str(),
"std::string") || !strcmp(mTypeName.c_str(),
"std::string*")) {
2749 const clang::Type *rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
2751 if (rawtype->isPointerType()) {
2753 clang::QualType pointee;
2754 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
2756 rawtype = pointee.getTypePtr();
2760 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2765 const clang::CXXRecordDecl *cxxdecl = rawtype->getAsCXXRecordDecl();
2769 if (version > 0)
return true;
2782 const clang::Type *rawtype =
m.getType().getTypePtr();
2785 clang::QualType pointee;
2786 while ( rawtype->isPointerType() && ((pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull()) && pointee.getTypePtr() != rawtype)
2788 rawtype = pointee.getTypePtr();
2802 if (rawtype->isFundamentalType() || rawtype->isEnumeralType()) {
2806 return rawtype->getAsCXXRecordDecl();
2815 const cling::Interpreter &interp,
2817 std::ostream& dictStream,
2819 bool isGenreflex=
false)
2821 const clang::CXXRecordDecl* decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2823 if (!decl || !decl->isCompleteDefinition()) {
2827 std::string fullname;
2839 (*WriteStreamerFunc)(cl, interp, normCtxt, dictStream, isGenreflex || cl.RequestStreamerInfo());
2841 ROOT::TMetaUtils::Info(
nullptr,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
2863 const cling::Interpreter &interpreter,
2866 const clang::ASTContext& Ctx = interpreter.getCI()->getASTContext();
2868 clang::QualType originalType = instanceType;
2872 if (llvm::isa<clang::PointerType>(instanceType.getTypePtr())) {
2874 clang::Qualifiers quals = instanceType.getQualifiers();
2875 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2876 if (newPointee != instanceType->getPointeeType()) {
2877 instanceType = Ctx.getPointerType(newPointee);
2879 instanceType = Ctx.getQualifiedType(instanceType, quals);
2881 return instanceType;
2886 if (llvm::isa<clang::ReferenceType>(instanceType.getTypePtr())) {
2888 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(instanceType.getTypePtr());
2889 clang::Qualifiers quals = instanceType.getQualifiers();
2890 clang::QualType newPointee =
AddDefaultParameters(instanceType->getPointeeType(), interpreter, normCtxt);
2892 if (newPointee != instanceType->getPointeeType()) {
2895 instanceType = Ctx.getLValueReferenceType(newPointee);
2897 instanceType = Ctx.getRValueReferenceType(newPointee);
2899 instanceType = Ctx.getQualifiedType(instanceType, quals);
2901 return instanceType;
2905 bool prefix_changed =
false;
2906 clang::NestedNameSpecifier *prefix =
nullptr;
2907 clang::Qualifiers prefix_qualifiers = instanceType.getLocalQualifiers();
2908 const clang::ElaboratedType* etype
2909 = llvm::dyn_cast<clang::ElaboratedType>(instanceType.getTypePtr());
2912 prefix = AddDefaultParametersNNS(Ctx, etype->getQualifier(), interpreter, normCtxt);
2913 prefix_changed = prefix != etype->getQualifier();
2914 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
2920 const clang::TemplateSpecializationType* TST
2921 = llvm::dyn_cast<const clang::TemplateSpecializationType>(instanceType.getTypePtr());
2923 const clang::ClassTemplateSpecializationDecl* TSTdecl
2924 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(instanceType.getTypePtr()->getAsCXXRecordDecl());
2936 bool mightHaveChanged =
false;
2937 if (TST && TSTdecl) {
2939 clang::Sema& S = interpreter.getCI()->getSema();
2940 clang::TemplateDecl *Template = TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
2941 clang::TemplateParameterList *Params = Template->getTemplateParameters();
2942 clang::TemplateParameterList::iterator Param = Params->
begin();
2946 unsigned int dropDefault = normCtxt.
GetConfig().DropDefaultArg(*Template);
2948 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
2949 llvm::SmallVector<clang::TemplateArgument, 4> canonArgs;
2950 llvm::ArrayRef<clang::TemplateArgument> template_arguments = TST->template_arguments();
2951 unsigned int Idecl = 0, Edecl = TSTdecl->getTemplateArgs().size();
2952 unsigned int maxAddArg = TSTdecl->getTemplateArgs().size() - dropDefault;
2953 for (
const clang::TemplateArgument *
I = template_arguments.begin(), *E = template_arguments.end(); Idecl != Edecl;
2954 I != E ? ++
I :
nullptr, ++Idecl, ++Param) {
2958 if (
I->getKind() == clang::TemplateArgument::Template) {
2959 clang::TemplateName templateName =
I->getAsTemplate();
2960 clang::TemplateDecl* templateDecl = templateName.getAsTemplateDecl();
2962 clang::DeclContext* declCtxt = templateDecl->getDeclContext();
2964 if (declCtxt && !templateName.getAsQualifiedTemplateName()){
2965 clang::NamespaceDecl* ns = clang::dyn_cast<clang::NamespaceDecl>(declCtxt);
2966 clang::NestedNameSpecifier* nns;
2968 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx, ns);
2969 }
else if (clang::TagDecl* TD = llvm::dyn_cast<clang::TagDecl>(declCtxt)) {
2970 nns = cling::utils::TypeName::CreateNestedNameSpecifier(Ctx,TD,
false );
2973 desArgs.push_back(*
I);
2976 clang::TemplateName UnderlyingTN(templateDecl);
2977 if (clang::UsingShadowDecl *USD = templateName.getAsUsingShadowDecl())
2978 UnderlyingTN = clang::TemplateName(USD);
2979 clang::TemplateName templateNameWithNSS ( Ctx.getQualifiedTemplateName(nns,
false, UnderlyingTN) );
2980 desArgs.push_back(clang::TemplateArgument(templateNameWithNSS));
2981 mightHaveChanged =
true;
2987 if (
I->getKind() != clang::TemplateArgument::Type) {
2988 desArgs.push_back(*
I);
2992 clang::QualType SubTy =
I->getAsType();
3001 if (SubTy != newSubTy) {
3002 mightHaveChanged =
true;
3003 desArgs.push_back(clang::TemplateArgument(newSubTy));
3005 desArgs.push_back(*
I);
3008 }
else if (!isStdDropDefault && Idecl < maxAddArg) {
3010 mightHaveChanged =
true;
3012 const clang::TemplateArgument& templateArg
3013 = TSTdecl->getTemplateArgs().get(Idecl);
3014 if (templateArg.getKind() != clang::TemplateArgument::Type) {
3015 desArgs.push_back(templateArg);
3018 clang::QualType SubTy = templateArg.getAsType();
3020 clang::SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3021 clang::SourceLocation RAngleLoc = TSTdecl->getSourceRange().getBegin();
3023 clang::TemplateTypeParmDecl *TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*Param);
3026 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
3027 bool HasDefaultArgs;
3028 clang::TemplateArgumentLoc ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
3038 if (ArgType.getArgument().isNull()
3039 || ArgType.getArgument().getKind() != clang::TemplateArgument::Type) {
3041 "Template parameter substitution failed for %s around %s\n",
3042 instanceType.getAsString().c_str(), SubTy.getAsString().c_str());
3045 clang::QualType BetterSubTy = ArgType.getArgument().getAsType();
3046 SubTy = cling::utils::Transform::GetPartiallyDesugaredType(Ctx,BetterSubTy,normCtxt.
GetConfig(),
true);
3049 desArgs.push_back(clang::TemplateArgument(SubTy));
3058 if (mightHaveChanged) {
3059 instanceType = Ctx.getTemplateSpecializationType(TST->getTemplateName(),
3061 TST->getCanonicalTypeInternal());
3065 if (!prefix_changed && !mightHaveChanged)
return originalType;
3067 instanceType = Ctx.getElaboratedType(clang::ETK_None,prefix,instanceType);
3068 instanceType = Ctx.getQualifiedType(instanceType,prefix_qualifiers);
3070 return instanceType;
3090 llvm::StringRef title;
3093 if (clang::AnnotateAttr *A =
m.getAttr<clang::AnnotateAttr>())
3094 title = A->getAnnotation();
3106 if (errnum) *errnum =
VALID;
3108 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
3109 size_t rightbracket = title.find(
']');
3110 if (rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
3112 std::string working;
3113 llvm::StringRef indexvar(title.data()+1,rightbracket-1);
3120 size_t indexvarlen = indexvar.size();
3121 for (
i=0;
i<indexvarlen;
i++) {
3122 if (!isspace(indexvar[
i])) {
3123 working += indexvar[
i];
3128 const char *tokenlist =
"*+-";
3129 char *current =
const_cast<char*
>(working.c_str());
3130 current = strtok(current,tokenlist);
3134 if (isdigit(current[0])) {
3135 for(
i=0;
i<strlen(current);
i++) {
3136 if (!isdigit(current[
i])) {
3141 if (errstr) *errstr = current;
3142 if (errnum) *errnum =
NOT_INT;
3143 return llvm::StringRef();
3148 const clang::CXXRecordDecl *parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext());
3149 const clang::FieldDecl *index1 =
nullptr;
3151 index1 = GetDataMemberFromAll(*parent_clxx, current );
3153 if ( IsFieldDeclInt(index1) ) {
3158 for(clang::RecordDecl::field_iterator field_iter = parent_clxx->field_begin(), end = parent_clxx->field_end();
3162 if ( field_iter->getNameAsString() ==
m.getNameAsString() ) {
3168 if (errstr) *errstr = current;
3169 if (errnum) *errnum =
NOT_DEF;
3170 return llvm::StringRef();
3172 if ( field_iter->getNameAsString() == index1->getNameAsString() ) {
3180 if (errstr) *errstr = current;
3181 if (errnum) *errnum =
NOT_INT;
3182 return llvm::StringRef();
3189 clang::Sema& SemaR =
const_cast<cling::Interpreter&
>(interp).getSema();
3190 index1 = GetDataMemberFromAllParents(SemaR, *parent_clxx, current);
3193 if ( IsFieldDeclInt(index1) ) {
3200 if (errnum) *errnum =
NOT_INT;
3201 if (errstr) *errstr = current;
3205 if (errnum) *errnum =
NOT_INT;
3206 if (errstr) *errstr = current;
3207 return llvm::StringRef();
3209 if ( found && (index1->getAccess() == clang::AS_private) ) {
3212 if (errstr) *errstr = current;
3214 return llvm::StringRef();
3221 if (errstr) *errstr = indexvar;
3222 if (errnum) *errnum =
UNKNOWN;
3223 return llvm::StringRef();
3228 current = strtok(
nullptr, tokenlist);
3244 while((
c = in[
i++])) {
3245 const char *repl =
nullptr;
3247 case '+': repl =
"pL";
break;
3248 case '-': repl =
"mI";
break;
3249 case '*': repl =
"mU";
break;
3250 case '/': repl =
"dI";
break;
3251 case '&': repl =
"aN";
break;
3252 case '%': repl =
"pE";
break;
3253 case '|': repl =
"oR";
break;
3254 case '^': repl =
"hA";
break;
3255 case '>': repl =
"gR";
break;
3256 case '<': repl =
"lE";
break;
3257 case '=': repl =
"eQ";
break;
3258 case '~': repl =
"wA";
break;
3259 case '.': repl =
"dO";
break;
3260 case '(': repl =
"oP";
break;
3261 case ')': repl =
"cP";
break;
3262 case '[': repl =
"oB";
break;
3263 case ']': repl =
"cB";
break;
3264 case '!': repl =
"nO";
break;
3265 case ',': repl =
"cO";
break;
3266 case '$': repl =
"dA";
break;
3267 case ' ': repl =
"sP";
break;
3268 case ':': repl =
"cL";
break;
3269 case '"': repl =
"dQ";
break;
3270 case '@': repl =
"aT";
break;
3271 case '\'': repl =
"sQ";
break;
3272 case '\\': repl =
"fI";
break;
3281 auto firstNonNumber = out.find_first_not_of(
"0123456789");
3282 if (firstNonNumber != std::string::npos)
3283 out.replace(0,firstNonNumber,
"");
3286static clang::SourceLocation
3288 clang::SourceLocation sourceLoc) {
3290 if (!sourceLoc.isFileID()) {
3291 return sourceManager.getExpansionRange(sourceLoc).getEnd();
3300 const cling::Interpreter& interp)
3330 using namespace clang;
3331 SourceLocation headerLoc = decl.getLocation();
3333 static const char invalidFilename[] =
"";
3334 if (!headerLoc.isValid())
return invalidFilename;
3336 HeaderSearch& HdrSearch = interp.getCI()->getPreprocessor().getHeaderSearchInfo();
3338 SourceManager& sourceManager = decl.getASTContext().getSourceManager();
3340 FileID headerFID = sourceManager.getFileID(headerLoc);
3341 SourceLocation includeLoc
3343 sourceManager.getIncludeLoc(headerFID));
3345 const FileEntry *headerFE = sourceManager.getFileEntryForID(headerFID);
3346 while (includeLoc.isValid() && sourceManager.isInSystemHeader(includeLoc)) {
3347 ConstSearchDirIterator *foundDir =
nullptr;
3350 assert(headerFE &&
"Couldn't find FileEntry from FID!");
3352 = HdrSearch.LookupFile(llvm::sys::path::filename(headerFE->getName()),
3354 true ,
nullptr, foundDir,
3355 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3363 headerFID = sourceManager.getFileID(includeLoc);
3364 headerFE = sourceManager.getFileEntryForID(headerFID);
3369 if (interp.getCI()->getLangOpts().Modules && !headerFE) {
3370 assert(decl.isFirstDecl() &&
"Couldn't trace back include from a decl"
3371 " that is not from an AST file");
3372 assert(StringRef(includeLoc.printToString(sourceManager)).startswith(
"<module-includes>"));
3376 sourceManager.getIncludeLoc(headerFID));
3379 if (!headerFE)
return invalidFilename;
3381 llvm::SmallString<256> headerFileName(headerFE->getName());
3384 llvm::sys::path::remove_dots(headerFileName,
true);
3395 bool isAbsolute = llvm::sys::path::is_absolute(headerFileName);
3396 clang::OptionalFileEntryRef FELong;
3398 for (llvm::sys::path::const_iterator
3399 IDir = llvm::sys::path::begin(headerFileName),
3400 EDir = llvm::sys::path::end(headerFileName);
3401 !FELong && IDir != EDir; ++IDir) {
3407 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3408 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3409 assert(trailingPart.data() + trailingPart.size()
3410 == headerFileName.data() + headerFileName.size()
3411 &&
"Mismatched partitioning of file name!");
3412 ConstSearchDirIterator* FoundDir =
nullptr;
3413 FELong = HdrSearch.LookupFile(trailingPart, SourceLocation(),
3414 true ,
nullptr, FoundDir,
3415 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3423 return invalidFilename;
3427 for (llvm::sys::path::reverse_iterator
3428 IDir = llvm::sys::path::rbegin(headerFileName),
3429 EDir = llvm::sys::path::rend(headerFileName);
3430 IDir != EDir; ++IDir) {
3431 size_t lenTrailing = headerFileName.size() - (IDir->data() - headerFileName.data());
3432 llvm::StringRef trailingPart(IDir->data(), lenTrailing);
3433 assert(trailingPart.data() + trailingPart.size()
3434 == headerFileName.data() + headerFileName.size()
3435 &&
"Mismatched partitioning of file name!");
3436 ConstSearchDirIterator* FoundDir =
nullptr;
3439 if (HdrSearch.LookupFile(trailingPart, SourceLocation(),
3440 true ,
nullptr, FoundDir,
3441 ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>>(),
3444 nullptr,
nullptr ) == FELong) {
3445 return trailingPart.str();
3449 return invalidFilename;
3455 const clang::QualType &qtype,
3456 const clang::ASTContext &astContext)
3458 std::string fqname = cling::utils::TypeName::GetFullyQualifiedName(qtype, astContext);
3467 const clang::QualType &qtype,
3468 const cling::Interpreter &interpreter)
3473 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3477 interpreter.getCI()->getASTContext());
3485 clang::ClassTemplateDecl*& ctd,
3486 clang::ClassTemplateSpecializationDecl*& ctsd)
3488 using namespace clang;
3489 const Type* theType = qt.getTypePtr();
3496 if (theType->isPointerType()) {
3500 if (
const RecordType* rType = llvm::dyn_cast<RecordType>(theType)) {
3501 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(rType->getDecl());
3503 ctd = ctsd->getSpecializedTemplate();
3508 if (
const SubstTemplateTypeParmType* sttpType = llvm::dyn_cast<SubstTemplateTypeParmType>(theType)){
3513 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(qt->getAsCXXRecordDecl());
3515 ctd = ctsd->getSpecializedTemplate();
3530 using namespace clang;
3531 ClassTemplateSpecializationDecl* ctsd;
3532 ClassTemplateDecl* ctd;
3546 using namespace clang;
3547 TemplateName theTemplateName;
3549 const Type* theType = qt.getTypePtr();
3551 if (
const TemplateSpecializationType* tst = llvm::dyn_cast_or_null<const TemplateSpecializationType>(theType)) {
3552 theTemplateName = tst->getTemplateName();
3555 theTemplateName = TemplateName(ctd);
3558 return theTemplateName;
3564 llvm::SmallVectorImpl<clang::TemplateArgument>& preceedingTArgs,
3565 const clang::NamedDecl& tPar,
3566 const cling::Interpreter& interp,
3570 using namespace clang;
3573 TemplateTypeParmDecl* ttpdPtr =
const_cast<TemplateTypeParmDecl*
>(llvm::dyn_cast<TemplateTypeParmDecl>(&tPar));
3574 if (!ttpdPtr)
return false;
3575 if (!ttpdPtr->hasDefaultArgument())
return false;
3578 QualType tParQualType = ttpdPtr->getDefaultArgument();
3579 const QualType tArgQualType = tArg.getAsType();
3586 if (tParQualType.getTypePtr() == tArgQualType.getTypePtr())
return true;
3597 const clang::ElaboratedType* etype
3598 = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3600 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3601 etype = llvm::dyn_cast<clang::ElaboratedType>(tParQualType.getTypePtr());
3604 const TemplateSpecializationType* tst =
3605 llvm::dyn_cast<TemplateSpecializationType>(tParQualType.getTypePtr());
3610 ClassTemplateSpecializationDecl* TSTdecl
3611 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(tArgQualType->getAsCXXRecordDecl());
3616 TemplateDecl *Template = tst->getTemplateName().getAsTemplateDecl();
3619 SourceLocation TemplateLoc = Template->getSourceRange ().getBegin();
3622 SourceLocation LAngleLoc = TSTdecl->getSourceRange().getBegin();
3627 TemplateArgument newArg = tArg;
3629 clang::Sema& S = interp.getCI()->getSema();
3630 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interp));
3631 llvm::SmallVector<clang::TemplateArgument, 4> canonArgs;
3632 bool HasDefaultArgs;
3633 TemplateArgumentLoc defTArgLoc = S.SubstDefaultTemplateArgumentIfAvailable(Template,
3642 newArg = defTArgLoc.getArgument();
3643 if (newArg.isNull() ||
3644 newArg.getKind() != clang::TemplateArgument::Type) {
3646 "Template parameter substitution failed!");
3649 ClassTemplateSpecializationDecl* nTSTdecl
3650 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(newArg.getAsType()->getAsCXXRecordDecl());
3653 isEqual = (nTSTdecl && nTSTdecl->getMostRecentDecl() == TSTdecl->getMostRecentDecl()) ||
3654 (tParQualType.getTypePtr() == newArg.getAsType().getTypePtr());
3666 const clang::NamedDecl& tPar)
3668 using namespace clang;
3669 const NonTypeTemplateParmDecl* nttpdPtr = llvm::dyn_cast<NonTypeTemplateParmDecl>(&tPar);
3670 if (!nttpdPtr)
return false;
3671 const NonTypeTemplateParmDecl& nttpd = *nttpdPtr;
3673 if (!nttpd.hasDefaultArgument())
3677 llvm::APSInt defaultValueAPSInt(64,
false);
3678 if (Expr* defArgExpr = nttpd.getDefaultArgument()) {
3679 const ASTContext& astCtxt = nttpdPtr->getASTContext();
3680 if (
auto Value = defArgExpr->getIntegerConstantExpr(astCtxt))
3681 defaultValueAPSInt = *
Value;
3684 const int value = tArg.getAsIntegral().getLimitedValue();
3687 return value == defaultValueAPSInt;
3697 using namespace clang;
3698 if (!nDecl)
return false;
3699 if (
const TemplateTypeParmDecl* ttpd = llvm::dyn_cast<TemplateTypeParmDecl>(nDecl))
3700 return ttpd->hasDefaultArgument();
3701 if (
const NonTypeTemplateParmDecl* nttpd = llvm::dyn_cast<NonTypeTemplateParmDecl>(nDecl))
3702 return nttpd->hasDefaultArgument();
3707static void KeepNParams(clang::QualType& normalizedType,
3708 const clang::QualType& vanillaType,
3709 const cling::Interpreter& interp,
3714 const clang::TemplateArgument &tArg,
3715 const cling::Interpreter& interp,
3717 const clang::ASTContext& astCtxt)
3720 using namespace clang;
3727 if (tArg.getKind() == clang::TemplateArgument::Type) {
3728 QualType thisNormQualType = normTArg.getAsType();
3729 QualType thisArgQualType = tArg.getAsType();
3734 normTArg = TemplateArgument(thisNormQualType);
3735 return (thisNormQualType != thisArgQualType);
3736 }
else if (normTArg.getKind() == clang::TemplateArgument::Pack) {
3737 assert( tArg.getKind() == clang::TemplateArgument::Pack );
3739 SmallVector<TemplateArgument, 2> desArgs;
3740 bool mightHaveChanged =
true;
3741 for (
auto I = normTArg.pack_begin(), E = normTArg.pack_end(),
3742 FI = tArg.pack_begin(), FE = tArg.pack_end();
3743 I != E && FI != FE; ++
I, ++FI)
3745 TemplateArgument pack_arg(*
I);
3747 desArgs.push_back(pack_arg);
3749 if (mightHaveChanged) {
3750 ASTContext &mutableCtx(
const_cast<ASTContext&
>(astCtxt) );
3751 normTArg = TemplateArgument::CreatePackCopy(mutableCtx, desArgs);
3753 return mightHaveChanged;
3764 const clang::QualType& vanillaType,
3765 const cling::Interpreter& interp,
3769 using namespace clang;
3773 ClassTemplateSpecializationDecl* ctsd;
3774 ClassTemplateDecl* ctd;
3781 QualType originalNormalizedType = normalizedType;
3783 const ASTContext& astCtxt = ctsd->getASTContext();
3788 if (llvm::isa<clang::PointerType>(normalizedType.getTypePtr())) {
3790 clang::Qualifiers quals = normalizedType.getQualifiers();
3791 auto valNormalizedType = normalizedType->getPointeeType();
3792 KeepNParams(valNormalizedType,vanillaType, interp, normCtxt);
3793 normalizedType = astCtxt.getPointerType(valNormalizedType);
3795 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3801 if (llvm::isa<clang::ReferenceType>(normalizedType.getTypePtr())) {
3803 bool isLValueRefTy = llvm::isa<clang::LValueReferenceType>(normalizedType.getTypePtr());
3804 clang::Qualifiers quals = normalizedType.getQualifiers();
3805 auto valNormType = normalizedType->getPointeeType();
3806 KeepNParams(valNormType, vanillaType, interp, normCtxt);
3810 normalizedType = astCtxt.getLValueReferenceType(valNormType);
3812 normalizedType = astCtxt.getRValueReferenceType(valNormType);
3814 normalizedType = astCtxt.getQualifiedType(normalizedType, quals);
3819 bool prefix_changed =
false;
3820 clang::NestedNameSpecifier* prefix =
nullptr;
3821 clang::Qualifiers prefix_qualifiers = normalizedType.getLocalQualifiers();
3822 const clang::ElaboratedType* etype
3823 = llvm::dyn_cast<clang::ElaboratedType>(normalizedType.getTypePtr());
3827 prefix = AddDefaultParametersNNS(astCtxt, etype->getQualifier(), interp, normCtxt);
3828 prefix_changed = prefix != etype->getQualifier();
3829 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3835 const clang::ClassTemplateDecl* ctdWithDefaultArgs = ctd;
3836 for (
const RedeclarableTemplateDecl* rd: ctdWithDefaultArgs->redecls()) {
3837 clang::TemplateParameterList* tpl = rd->getTemplateParameters();
3838 if (tpl->getMinRequiredArguments () < tpl->size()) {
3839 ctdWithDefaultArgs = llvm::dyn_cast<clang::ClassTemplateDecl>(rd);
3844 if (!ctdWithDefaultArgs) {
3845 Error(
"KeepNParams",
"Not found template default arguments\n");
3846 normalizedType=originalNormalizedType;
3850 TemplateParameterList* tParsPtr = ctdWithDefaultArgs->getTemplateParameters();
3851 const TemplateParameterList& tPars = *tParsPtr;
3852 const TemplateArgumentList& tArgs = ctsd->getTemplateArgs();
3856 if (theTemplateName.isNull()) {
3857 normalizedType=originalNormalizedType;
3861 const TemplateSpecializationType* normalizedTst =
3862 llvm::dyn_cast<TemplateSpecializationType>(normalizedType.getTypePtr());
3863 if (!normalizedTst) {
3864 normalizedType=originalNormalizedType;
3868 const clang::ClassTemplateSpecializationDecl* TSTdecl
3869 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(normalizedType.getTypePtr()->getAsCXXRecordDecl());
3877 llvm::SmallVector<TemplateArgument, 4> argsToKeep;
3879 const int nArgs = tArgs.size();
3880 const auto &normArgs = normalizedTst->template_arguments();
3881 const int nNormArgs = normArgs.size();
3883 bool mightHaveChanged =
false;
3886 for (
int formal = 0, inst = 0; formal != nArgs; ++formal, ++inst) {
3887 const NamedDecl* tParPtr = tPars.getParam(formal);
3889 Error(
"KeepNParams",
"The parameter number %s is null.\n", formal);
3896 if (formal == nNormArgs || inst == nNormArgs)
break;
3898 const TemplateArgument& tArg = tArgs.get(formal);
3899 TemplateArgument normTArg(normArgs[inst]);
3901 bool shouldKeepArg = nArgsToKeep < 0 || inst < nArgsToKeep;
3902 if (isStdDropDefault) shouldKeepArg =
false;
3911 if ( tParPtr->isTemplateParameterPack() ) {
3916 for( ; inst != nNormArgs; ++inst) {
3917 normTArg = normArgs[inst];
3919 argsToKeep.push_back(normTArg);
3925 argsToKeep.push_back(normTArg);
3928 if (!isStdDropDefault) {
3930 mightHaveChanged =
true;
3940 auto argKind = tArg.getKind();
3941 if (argKind == clang::TemplateArgument::Type){
3943 equal =
areEqualTypes(tArg, argsToKeep, *tParPtr, interp, normCtxt);
3944 }
else if (argKind == clang::TemplateArgument::Integral){
3949 argsToKeep.push_back(normTArg);
3951 mightHaveChanged =
true;
3957 if (!prefix_changed && !mightHaveChanged) {
3958 normalizedType = originalNormalizedType;
3963 if (mightHaveChanged) {
3964 Qualifiers qualifiers = normalizedType.getLocalQualifiers();
3965 normalizedType = astCtxt.getTemplateSpecializationType(theTemplateName,
3967 normalizedType.getTypePtr()->getCanonicalTypeInternal());
3968 normalizedType = astCtxt.getQualifiedType(normalizedType, qualifiers);
3974 normalizedType = astCtxt.getElaboratedType(clang::ETK_None,prefix,normalizedType);
3975 normalizedType = astCtxt.getQualifiedType(normalizedType,prefix_qualifiers);
3989 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
3992 cling::Interpreter::PushTransactionRAII RAII(
const_cast<cling::Interpreter*
>(&interpreter));
3993 clang::QualType normalizedType = cling::utils::Transform::GetPartiallyDesugaredType(ctxt,
type, normCtxt.
GetConfig(),
true );
4001 return normalizedType;
4015 if (
type.isNull()) {
4022 clang::ASTContext &ctxt = interpreter.getCI()->getASTContext();
4023 clang::PrintingPolicy policy(ctxt.getPrintingPolicy());
4024 policy.SuppressTagKeyword =
true;
4025 policy.SuppressScope =
true;
4026 policy.AnonymousTagLocations =
false;
4031 std::string normalizedNameStep1;
4034 cling::Interpreter::PushTransactionRAII clingRAII(
const_cast<cling::Interpreter*
>(&interpreter));
4035 normalizedType.getAsStringInternal(normalizedNameStep1,policy);
4045 if (norm_name.length()>2 && norm_name[0]==
':' && norm_name[1]==
':') {
4046 norm_name.erase(0,2);
4054 const clang::TypeDecl* typeDecl,
4055 const cling::Interpreter &interpreter)
4058 const clang::Sema &sema = interpreter.getSema();
4059 clang::ASTContext& astCtxt = sema.getASTContext();
4060 clang::QualType qualType = astCtxt.getTypeDeclType(typeDecl);
4069std::pair<std::string,clang::QualType>
4071 const cling::Interpreter &interpreter,
4075 std::string thisTypeName;
4079 if (!hasChanged)
return std::make_pair(thisTypeName,thisType);
4083 "Name changed from %s to %s\n", thisTypeName.c_str(), thisTypeNameForIO.c_str());
4086 auto& lookupHelper = interpreter.getLookupHelper();
4088 const clang::Type* typePtrForIO;
4089 lookupHelper.findScope(thisTypeNameForIO,
4090 cling::LookupHelper::DiagSetting::NoDiagnostics,
4094 if (!typePtrForIO) {
4096 "Type not found: %s.",thisTypeNameForIO.c_str());
4099 clang::QualType typeForIO(typePtrForIO,0);
4102 if (!typeForIO->isRecordType()) {
4103 return std::make_pair(thisTypeNameForIO,typeForIO);
4106 auto thisDeclForIO = typeForIO->getAsCXXRecordDecl();
4107 if (!thisDeclForIO) {
4109 "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());
4110 return std::make_pair(thisTypeName,thisType);
4113 return std::make_pair(thisTypeNameForIO,typeForIO);
4119 const cling::Interpreter &interpreter,
4131 std::string dictFileName(moduleName);
4132 dictFileName +=
"_rdict.pcm";
4133 return dictFileName;
4137 llvm::errs() << llvm::StringRef(commentStart, 80) <<
'\n';
4163 clang::SourceManager& sourceManager = decl.getASTContext().getSourceManager();
4164 clang::SourceLocation sourceLocation = decl.getEndLoc();
4167 sourceLocation = sourceManager.getExpansionRange(sourceLocation).getEnd();
4175 if (!decl.hasOwningModule() && sourceManager.isLoadedSourceLocation(sourceLocation)) {
4181 const char *commentStart = sourceManager.getCharacterData(sourceLocation, &invalid);
4185 bool skipToSemi =
true;
4186 if (
const clang::FunctionDecl* FD = clang::dyn_cast<clang::FunctionDecl>(&decl)) {
4187 if (FD->isImplicit()) {
4191 if (FD->isExplicitlyDefaulted() || FD->isDeletedAsWritten()) {
4195 }
else if (FD->doesThisDeclarationHaveABody()) {
4198 assert((decl.getEndLoc() != sourceLocation || *commentStart ==
'}'
4200 &&
"Expected macro or end of body at '}'");
4201 if (*commentStart) ++commentStart;
4204 while (*commentStart && isspace(*commentStart)
4205 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4208 if (*commentStart ==
';') ++commentStart;
4212 }
else if (
const clang::EnumConstantDecl* ECD
4213 = clang::dyn_cast<clang::EnumConstantDecl>(&decl)) {
4215 if (ECD->getNextDeclInContext())
4216 while (*commentStart && *commentStart !=
',' && *commentStart !=
'\r' && *commentStart !=
'\n')
4224 while (*commentStart && *commentStart !=
';' && *commentStart !=
'\r' && *commentStart !=
'\n')
4226 if (*commentStart ==
';') ++commentStart;
4230 while ( *commentStart && isspace(*commentStart)
4231 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4235 if (commentStart[0] !=
'/' ||
4236 (commentStart[1] !=
'/' && commentStart[1] !=
'*')) {
4246 unsigned int skipChars = 2;
4247 if (commentStart[0] ==
'/' &&
4248 commentStart[1] ==
'/' &&
4249 (commentStart[2] ==
'/' || commentStart[2] ==
'!') &&
4250 commentStart[3] ==
'<') {
4252 }
else if (commentStart[0] ==
'/' &&
4253 commentStart[1] ==
'*' &&
4254 (commentStart[2] ==
'*' || commentStart[2] ==
'!') &&
4255 commentStart[3] ==
'<') {
4259 commentStart += skipChars;
4262 while ( *commentStart && isspace(*commentStart)
4263 && *commentStart !=
'\n' && *commentStart !=
'\r') {
4266 const char* commentEnd = commentStart;
4268 while (*commentEnd && *commentEnd !=
'\n' && *commentEnd !=
'\r') {
4274 while (commentEnd > commentStart && isspace(commentEnd[-1])) {
4280 unsigned offset = commentStart - sourceManager.getCharacterData(sourceLocation);
4281 *loc = sourceLocation.getLocWithOffset(
offset - 1);
4284 return llvm::StringRef(commentStart, commentEnd - commentStart);
4292 if (!decl)
return false;
4294 auto& sema = interpreter.getCI()->getSema();
4295 auto maybeMacroLoc = decl->getLocation();
4297 if (!maybeMacroLoc.isMacroID())
return false;
4299 static const std::vector<std::string> signatures =
4300 {
"ClassDef",
"ClassDefOverride",
"ClassDefNV",
"ClassDefInline",
"ClassDefInlineOverride",
"ClassDefInlineNV" };
4302 for (
auto &
name : signatures)
4303 if (sema.findMacroSpelling(maybeMacroLoc,
name))
4317 clang::SourceLocation *loc,
4318 const cling::Interpreter &interpreter)
4320 using namespace clang;
4322 const Decl* DeclFileLineDecl
4323 = interpreter.getLookupHelper().findFunctionProto(&decl,
"DeclFileLine",
"",
4324 cling::LookupHelper::NoDiagnostics);
4328 SourceLocation commentSLoc;
4330 if (comment.size()) {
4337 return llvm::StringRef();
4346 const clang::Type *rawtype =
type.getTypePtr();
4349 if (rawtype->isElaboratedTypeSpecifier() ) {
4350 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4352 if (rawtype->isArrayType()) {
4353 rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
4355 if (rawtype->isPointerType() || rawtype->isReferenceType() ) {
4357 clang::QualType pointee;
4358 while ( (pointee = rawtype->getPointeeType()) , pointee.getTypePtrOrNull() && pointee.getTypePtr() != rawtype)
4360 rawtype = pointee.getTypePtr();
4362 if (rawtype->isElaboratedTypeSpecifier() ) {
4363 rawtype = rawtype->getCanonicalTypeInternal().getTypePtr();
4365 if (rawtype->isArrayType()) {
4366 rawtype = rawtype->getBaseElementTypeUnsafe ();
4370 if (rawtype->isArrayType()) {
4371 rawtype = rawtype->getBaseElementTypeUnsafe ();
4382 if (ctxt.isNamespace() || ctxt.isTranslationUnit())
4384 else if(
const auto parentdecl = llvm::dyn_cast<clang::CXXRecordDecl>(&ctxt))
4397 const clang::DeclContext *ctxt = decl.getDeclContext();
4398 switch (decl.getAccess()) {
4399 case clang::AS_public:
4401 case clang::AS_protected:
4403 case clang::AS_private:
4405 case clang::AS_none:
4409 assert(
false &&
"Unexpected value for the access property value in Clang");
4419 return cling::utils::Analyze::IsStdClass(cl);
4429 if (cling::utils::Analyze::IsStdClass(cl)) {
4430 static const char *names[] =
4431 {
"shared_ptr",
"__shared_ptr",
4432 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4433 llvm::StringRef clname(cl.getName());
4434 for(
auto &&
name : names) {
4435 if (clname ==
name)
return true;
4445 const clang::CXXRecordDecl ¤tCl)
4448 if (&cl == ¤tCl)
return true;
4450 const clang::CXXRecordDecl* previous = currentCl.getPreviousDecl();
4453 if (
nullptr == previous){
4472 const clang::CXXRecordDecl *thisDecl =
4473 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(lh.findScope(typ, cling::LookupHelper::WithDiagnostics));
4477 Error(
"IsOfType",
"Record decl of type %s not found in the AST.", typ.c_str());
4482 const clang::CXXRecordDecl *mostRecentDecl = thisDecl->getMostRecentDecl();
4508 auto *nsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext());
4509 if (cl.getName() !=
"RVec" || nsDecl ==
nullptr || nsDecl->getName() !=
"VecOps")
4512 auto *parentNsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext()->getParent());
4513 if (parentNsDecl ==
nullptr || parentNsDecl->getName() !=
"ROOT")
4521 using namespace clang;
4522 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4523 bool VisitTypedefType(
const TypedefType* TD) {
4526 bool VisitArrayType(
const ArrayType* AT) {
4527 return Visit(AT->getElementType().getTypePtr());
4529 bool VisitDecltypeType(
const DecltypeType* DT) {
4530 return Visit(DT->getUnderlyingType().getTypePtr());
4532 bool VisitPointerType(
const PointerType* PT) {
4533 return Visit(PT->getPointeeType().getTypePtr());
4535 bool VisitReferenceType(
const ReferenceType* RT) {
4536 return Visit(RT->getPointeeType().getTypePtr());
4538 bool VisitSubstTemplateTypeParmType(
const SubstTemplateTypeParmType* STST) {
4539 return Visit(STST->getReplacementType().getTypePtr());
4541 bool VisitTemplateSpecializationType(
const TemplateSpecializationType* TST) {
4542 for (
const TemplateArgument &
TA : TST->template_arguments()) {
4543 if (
TA.getKind() == TemplateArgument::Type && Visit(
TA.getAsType().getTypePtr()))
4548 bool VisitTemplateTypeParmType(
const TemplateTypeParmType* TTPT) {
4551 bool VisitTypeOfType(
const TypeOfType* TOT) {
4552 return TOT->getUnmodifiedType().getTypePtr();
4554 bool VisitElaboratedType(
const ElaboratedType* ET) {
4555 NestedNameSpecifier* NNS = ET->getQualifier();
4557 if (NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4558 if (Visit(NNS->getAsType()))
4561 NNS = NNS->getPrefix();
4563 return Visit(ET->getNamedType().getTypePtr());
4584 using namespace llvm;
4585 using namespace clang;
4586 const clang::ASTContext &Ctxt =
instance->getAsCXXRecordDecl()->getASTContext();
4589 const clang::ElaboratedType* etype
4590 = llvm::dyn_cast<clang::ElaboratedType>(
input.getTypePtr());
4594 clang::Qualifiers scope_qualifiers =
input.getLocalQualifiers();
4595 assert(
instance->getAsCXXRecordDecl() !=
nullptr &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4597 clang::NestedNameSpecifier *scope = ReSubstTemplateArgNNS(Ctxt,etype->getQualifier(),
instance);
4600 if (scope) subTy = Ctxt.getElaboratedType(clang::ETK_None,scope,subTy);
4601 subTy = Ctxt.getQualifiedType(subTy,scope_qualifiers);
4605 QualType QT =
input;
4609 if (isa<clang::PointerType>(QT.getTypePtr())) {
4611 Qualifiers quals = QT.getQualifiers();
4614 if (nQT == QT->getPointeeType())
return QT;
4616 QT = Ctxt.getPointerType(nQT);
4618 QT = Ctxt.getQualifiedType(QT, quals);
4624 if (isa<ReferenceType>(QT.getTypePtr())) {
4626 bool isLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
4627 Qualifiers quals = QT.getQualifiers();
4630 if (nQT == QT->getPointeeType())
return QT;
4634 QT = Ctxt.getLValueReferenceType(nQT);
4636 QT = Ctxt.getRValueReferenceType(nQT);
4638 QT = Ctxt.getQualifiedType(QT, quals);
4644 if (isa<clang::ArrayType>(QT.getTypePtr())) {
4646 Qualifiers quals = QT.getQualifiers();
4648 if (
const auto arr = dyn_cast<ConstantArrayType>(QT.getTypePtr())) {
4651 if (newQT == arr->getElementType())
return QT;
4652 QT = Ctxt.getConstantArrayType(newQT,
4655 arr->getSizeModifier(),
4656 arr->getIndexTypeCVRQualifiers());
4658 }
else if (
const auto arr = dyn_cast<DependentSizedArrayType>(QT.getTypePtr())) {
4661 if (newQT == QT)
return QT;
4662 QT = Ctxt.getDependentSizedArrayType (newQT,
4664 arr->getSizeModifier(),
4665 arr->getIndexTypeCVRQualifiers(),
4666 arr->getBracketsRange());
4668 }
else if (
const auto arr = dyn_cast<IncompleteArrayType>(QT.getTypePtr())) {
4671 if (newQT == arr->getElementType())
return QT;
4672 QT = Ctxt.getIncompleteArrayType (newQT,
4673 arr->getSizeModifier(),
4674 arr->getIndexTypeCVRQualifiers());
4676 }
else if (
const auto arr = dyn_cast<VariableArrayType>(QT.getTypePtr())) {
4679 if (newQT == arr->getElementType())
return QT;
4680 QT = Ctxt.getVariableArrayType (newQT,
4682 arr->getSizeModifier(),
4683 arr->getIndexTypeCVRQualifiers(),
4684 arr->getBracketsRange());
4688 QT = Ctxt.getQualifiedType(QT, quals);
4693 etype = llvm::dyn_cast<clang::ElaboratedType>(
instance);
4695 instance = etype->getNamedType().getTypePtr();
4699 const clang::TemplateSpecializationType* TST
4700 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
instance);
4702 if (!TST)
return input;
4704 const clang::ClassTemplateSpecializationDecl* TSTdecl
4705 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(
instance->getAsCXXRecordDecl());
4707 if (!TSTdecl)
return input;
4709 const clang::SubstTemplateTypeParmType *substType
4710 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(
input.getTypePtr());
4714 const clang::ClassTemplateDecl *replacedCtxt =
nullptr;
4716 const clang::DeclContext *replacedDeclCtxt = substType->getReplacedParameter()->getDeclContext();
4717 const clang::CXXRecordDecl *decl = llvm::dyn_cast<clang::CXXRecordDecl>(replacedDeclCtxt);
4718 unsigned int index = substType->getReplacedParameter()->getIndex();
4721 if (decl->getKind() == clang::Decl::ClassTemplatePartialSpecialization) {
4722 const clang::ClassTemplatePartialSpecializationDecl *spec = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(decl);
4724 unsigned int depth = substType->getReplacedParameter()->getDepth();
4726 const TemplateArgument *instanceArgs = spec->getTemplateArgs().data();
4727 unsigned int instanceNArgs = spec->getTemplateArgs().size();
4731 for(
unsigned int A = 0; A < instanceNArgs; ++A) {
4732 if (instanceArgs[A].getKind() == clang::TemplateArgument::Type) {
4733 clang::QualType argQualType = instanceArgs[A].getAsType();
4735 const clang::TemplateTypeParmType *replacementType;
4737 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(argQualType);
4739 if (!replacementType) {
4740 const clang::SubstTemplateTypeParmType *argType
4741 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(argQualType);
4743 clang::QualType replacementQT = argType->getReplacementType();
4744 replacementType = llvm::dyn_cast<clang::TemplateTypeParmType>(replacementQT);
4747 if (replacementType &&
4748 depth == replacementType->getDepth() &&
4749 index == replacementType->getIndex() )
4756 replacedCtxt = spec->getSpecializedTemplate();
4758 replacedCtxt = decl->getDescribedClassTemplate();
4760 }
else if (
auto const declguide = llvm::dyn_cast<clang::CXXDeductionGuideDecl>(replacedDeclCtxt)) {
4761 replacedCtxt = llvm::dyn_cast<clang::ClassTemplateDecl>(declguide->getDeducedTemplate());
4762 }
else if (
auto const ctdecl = llvm::dyn_cast<clang::ClassTemplateDecl>(replacedDeclCtxt)) {
4763 replacedCtxt = ctdecl;
4765 std::string astDump;
4766 llvm::raw_string_ostream
ostream(astDump);
4769 ROOT::TMetaUtils::Warning(
"ReSubstTemplateArg",
"Unexpected type of declaration context for template parameter: %s.\n\tThe responsible class is:\n\t%s\n",
4770 replacedDeclCtxt->getDeclKindName(), astDump.c_str());
4771 replacedCtxt =
nullptr;
4774 if (replacedCtxt && replacedCtxt->getCanonicalDecl() == TSTdecl->getSpecializedTemplate()->getCanonicalDecl())
4776 const auto &TAs = TST->template_arguments();
4777 if (
index >= TAs.size()) {
4783 }
else if (TAs[
index].getKind() == clang::TemplateArgument::Type) {
4784 return TAs[
index].getAsType();
4793 const clang::TemplateSpecializationType* inputTST
4794 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
input.getTypePtr());
4795 const clang::ASTContext& astCtxt = TSTdecl->getASTContext();
4798 bool mightHaveChanged =
false;
4799 llvm::SmallVector<clang::TemplateArgument, 4> desArgs;
4800 for (
const clang::TemplateArgument &
TA : inputTST->template_arguments()) {
4801 if (
TA.getKind() != clang::TemplateArgument::Type) {
4802 desArgs.push_back(
TA);
4806 clang::QualType SubTy =
TA.getAsType();
4808 if (llvm::isa<clang::ElaboratedType>(SubTy)
4809 || llvm::isa<clang::SubstTemplateTypeParmType>(SubTy)
4810 || llvm::isa<clang::TemplateSpecializationType>(SubTy)) {
4812 mightHaveChanged = SubTy != newSubTy;
4813 if (!newSubTy.isNull()) {
4814 desArgs.push_back(clang::TemplateArgument(newSubTy));
4817 desArgs.push_back(
TA);
4821 if (mightHaveChanged) {
4822 clang::Qualifiers qualifiers =
input.getLocalQualifiers();
4823 input = astCtxt.getTemplateSpecializationType(inputTST->getTemplateName(),
4825 inputTST->getCanonicalTypeInternal());
4826 input = astCtxt.getQualifiedType(
input, qualifiers);
4838 if ( nArgsToRemove == 0 ||
name ==
"")
4845 unsigned int nArgsRemoved=0;
4846 unsigned int nBraces=0;
4848 while (nArgsRemoved!=nArgsToRemove && cur<
length){
4850 if (
c ==
'<') nBraces++;
4851 if (
c ==
'>') nBraces--;
4852 if (
c ==
',' && nBraces==1 ) nArgsRemoved++;
4866 static const char *stls[] =
4867 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
4868 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
"RVec",
nullptr};
4882 for(
int k=1;stls[k];k++) {
if (
type.equals(stls[k]))
return values[k];}
4893 TND = TND->getMostRecentDecl();
4894 while (TND && !(TND->hasAttrs()))
4895 TND = TND->getPreviousDecl();
4907 TD = TD->getMostRecentDecl();
4908 while (TD && !(TD->hasAttrs() && TD->isThisDeclarationADefinition()))
4909 TD = TD->getPreviousDecl();
4918 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4920 const clang::DeclContext* enclosingNamespaceDeclCtxt = decl.getDeclContext();
4921 if (!enclosingNamespaceDeclCtxt)
return;
4923 const clang::NamespaceDecl* enclosingNamespace =
4924 clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4925 if (!enclosingNamespace)
return;
4927 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4928 enclosingNamespace->isInline()));
4938 std::list<std::pair<std::string,bool> >& enclosingNamespaces)
4940 const clang::DeclContext* enclosingNamespaceDeclCtxt = ctxt.getParent ();
4943 if (!enclosingNamespaceDeclCtxt) {
4949 const clang::NamespaceDecl* enclosingNamespace = clang::dyn_cast<clang::NamespaceDecl>(enclosingNamespaceDeclCtxt);
4950 if (!enclosingNamespace)
return;
4953 enclosingNamespaces.push_back(std::make_pair(enclosingNamespace->getNameAsString(),
4954 enclosingNamespace->isInline()));
4965 std::list<std::pair<std::string,unsigned int> >& enclosingSc)
4967 const clang::DeclContext* enclosingDeclCtxt = decl.getDeclContext();
4968 if (!enclosingDeclCtxt)
return nullptr;
4970 unsigned int scopeType;
4972 if (
auto enclosingNamespacePtr =
4973 clang::dyn_cast<clang::NamespaceDecl>(enclosingDeclCtxt)){
4974 scopeType= enclosingNamespacePtr->isInline() ? 1 : 0;
4975 enclosingSc.push_back(std::make_pair(enclosingNamespacePtr->getNameAsString(),scopeType));
4979 if (
auto enclosingClassPtr =
4980 clang::dyn_cast<clang::RecordDecl>(enclosingDeclCtxt)){
4981 return enclosingClassPtr;
4993 std::string::size_type beginVar = 0;
4994 std::string::size_type endVar = 0;
4995 while ((beginVar = txt.find(
'$', beginVar)) != std::string::npos
4996 && beginVar + 1 < txt.length()) {
4997 std::string::size_type beginVarName = beginVar + 1;
4998 std::string::size_type endVarName = std::string::npos;
4999 if (txt[beginVarName] ==
'(') {
5001 endVarName = txt.find(
')', beginVarName);
5003 if (endVarName == std::string::npos) {
5005 varname, txt.c_str() + beginVar);
5008 endVar = endVarName + 1;
5011 beginVarName = beginVar + 1;
5012 endVarName = beginVarName;
5013 while (isalnum(txt[endVarName]) || txt[endVarName] ==
'_')
5015 endVar = endVarName;
5018 const char* val = getenv(txt.substr(beginVarName,
5019 endVarName - beginVarName).c_str());
5022 txt.replace(beginVar, endVar - beginVar, val);
5023 int lenval = strlen(val);
5024 int delta = lenval - (endVar - beginVar);
5028 beginVar = endVar + 1;
5040 const char* envInclPath = getenv(
"ROOT_INCLUDE_PATH");
5044 std::istringstream envInclPathsStream(envInclPath);
5045 std::string inclPath;
5046 while (std::getline(envInclPathsStream, inclPath,
':')) {
5049 if (!inclPath.empty()) {
5050 clingArgs.push_back(
"-I");
5051 clingArgs.push_back(inclPath);
5062 size_t start_pos = 0;
5067 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
5068 str.replace(start_pos, from.length(), to);
5069 start_pos += to.length();
5070 if (recurse) changed =
true;
5086 if (theString.size() < theSubstring.size())
return false;
5087 const unsigned int theSubstringSize = theSubstring.size();
5088 return 0 == theString.compare(theString.size() - theSubstringSize,
5097 if (theString.size() < theSubstring.size())
return false;
5098 const unsigned int theSubstringSize = theSubstring.size();
5099 return 0 == theString.compare(0,
5117 size_t linkdeflen = 9;
5119 if (0 == strncasecmp(
filename + (
len - linkdeflen),
"linkdef", linkdeflen - 2)
5135 return llvm::sys::path::extension(
filename) ==
".h" ||
5136 llvm::sys::path::extension(
filename) ==
".hh" ||
5137 llvm::sys::path::extension(
filename) ==
".hpp" ||
5138 llvm::sys::path::extension(
filename) ==
".H" ||
5139 llvm::sys::path::extension(
filename) ==
".h++" ||
5140 llvm::sys::path::extension(
filename) ==
"hxx" ||
5141 llvm::sys::path::extension(
filename) ==
"Hxx" ||
5142 llvm::sys::path::extension(
filename) ==
"HXX";
5148 cling::Interpreter::IgnoreFilesFunc_t ignoreFiles,
5149 const cling::Interpreter &interp,
5152 clang::Sema &sema = interp.getSema();
5153 cling::Transaction theTransaction(sema);
5154 std::set<clang::Decl *> addedDecls;
5155 for (
auto decl : decls) {
5157 clang::Decl *ncDecl =
const_cast<clang::Decl *
>(decl);
5158 theTransaction.append(ncDecl);
5160 std::string newFwdDecl;
5161 llvm::raw_string_ostream llvmOstr(newFwdDecl);
5163 std::string locallogs;
5164 llvm::raw_string_ostream llvmLogStr(locallogs);
5165 interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr,
true,
5166 logs ? &llvmLogStr :
nullptr, ignoreFiles);
5170 logs->swap(locallogs);
5182 std::string& defString)
5194 std::string& defString)
5196 std::list<std::pair<std::string,unsigned int> > enclosingNamespaces;
5199 if (rcdPtr)
return rcdPtr;
5202 static const std::string scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5204 std::string scopeName;
5205 std::string scopeContent;
5206 unsigned int scopeIndex;
5207 for (
auto const & encScope : enclosingNamespaces){
5208 scopeIndex = encScope.second;
5209 scopeName = encScope.first;
5210 scopeContent =
" { " + defString +
" }";
5211 defString = scopeType[scopeIndex] +
5233 const clang::TemplateParameterList& tmplParamList,
5234 const cling::Interpreter& interpreter)
5237 for (
auto prmIt = tmplParamList.begin();
5238 prmIt != tmplParamList.end(); prmIt++){
5240 if (prmIt != tmplParamList.begin())
5241 templateArgs +=
", ";
5243 auto nDecl = *prmIt;
5244 std::string typeName;
5247 if (llvm::isa<clang::TemplateTypeParmDecl>(nDecl)){
5248 typeName =
"typename ";
5249 if (nDecl->isParameterPack())
5251 typeName += (*prmIt)->getNameAsString();
5254 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(nDecl)){
5255 auto theType = nttpd->getType();
5258 if (theType.getAsString().find(
"enum") != std::string::npos){
5259 std::string astDump;
5260 llvm::raw_string_ostream
ostream(astDump);
5263 ROOT::TMetaUtils::Warning(
nullptr,
"Forward declarations of templates with enums as template parameters. The responsible class is: %s\n", astDump.c_str());
5272 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(nDecl)){
5275 std::string astDump;
5276 llvm::raw_string_ostream
ostream(astDump);
5279 ROOT::TMetaUtils::Error(
nullptr,
"Cannot reconstruct template template parameter forward declaration for %s\n", astDump.c_str());
5284 templateArgs += typeName;
5295 const cling::Interpreter& interpreter,
5296 std::string& defString)
5298 std::string templatePrefixString;
5299 auto tmplParamList= templDecl.getTemplateParameters();
5300 if (!tmplParamList){
5302 "Cannot extract template parameter list for %s",
5303 templDecl.getNameAsString().c_str());
5310 "Problems with arguments for forward declaration of class %s\n",
5311 templDecl.getNameAsString().c_str());
5314 templatePrefixString =
"template " + templatePrefixString +
" ";
5316 defString = templatePrefixString +
"class ";
5317 if (templDecl.isParameterPack())
5318 defString +=
"... ";
5319 defString += templDecl.getNameAsString();
5320 if (llvm::isa<clang::TemplateTemplateParmDecl>(&templDecl)) {
5334 std::string& argFwdDecl,
5335 const cling::Interpreter& interpreter,
5336 bool acceptStl=
false)
5342 if (clang::TemplateArgument::Type != arg.getKind())
return 0;
5344 auto argQualType = arg.getAsType();
5347 while (llvm::isa<clang::PointerType>(argQualType.getTypePtr())) argQualType = argQualType->getPointeeType();
5349 auto argTypePtr = argQualType.getTypePtr();
5352 if (llvm::isa<clang::EnumType>(argTypePtr)){
5357 if (llvm::isa<clang::BuiltinType>(argTypePtr)){
5362 if (
auto tdTypePtr = llvm::dyn_cast<clang::TypedefType>(argTypePtr)) {
5367 if (
auto argRecTypePtr = llvm::dyn_cast<clang::RecordType>(argTypePtr)){
5369 if (
auto argRecDeclPtr = argRecTypePtr->getDecl()){
5382 const cling::Interpreter& interpreter,
5383 std::string& defString,
5384 const std::string &normalizedName)
5388 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)) {
5389 if (
const auto *specDef = tmplSpecDeclPtr->getDefinition()) {
5390 if (specDef->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization)
5394 std::cout <<
" Forward declaring template spec " << normalizedName <<
":\n";
5395 for (
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()) {
5396 std::string argFwdDecl;
5399 std::cout <<
" o Template argument ";
5401 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5403 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5410 defString += argFwdDecl +
'\n';
5412 defString +=
"template <> class " + normalizedName +
';';
5426 const cling::Interpreter& interpreter,
5427 std::string& defString,
5435 if (!recordDecl.getIdentifier())
5439 std::string argsFwdDecl;
5441 if (
auto tmplSpecDeclPtr = llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(&recordDecl)){
5442 std::string argFwdDecl;
5444 std::cout <<
"Class " << recordDecl.getNameAsString()
5445 <<
" is a template specialisation. Treating its arguments.\n";
5446 for(
auto arg : tmplSpecDeclPtr->getTemplateArgs().asArray()){
5449 std::cout <<
" o Template argument ";
5451 std::cout <<
"successfully treated. Arg fwd decl: " << argFwdDecl << std::endl;
5453 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5460 argsFwdDecl+=argFwdDecl;
5464 defString=argsFwdDecl;
5469 if (
auto tmplDeclPtr = tmplSpecDeclPtr->getSpecializedTemplate()){
5472 defString = argsFwdDecl +
"\n" + defString;
5477 defString =
"class " + recordDecl.getNameAsString() +
";";
5478 const clang::RecordDecl* rcd =
EncloseInScopes(recordDecl, defString);
5486 defString = argsFwdDecl +
"\n" + defString;
5497 const cling::Interpreter& interpreter,
5498 std::string& fwdDeclString,
5499 std::unordered_set<std::string>* fwdDeclSetPtr)
5501 std::string buffer = tdnDecl.getNameAsString();
5502 std::string underlyingName;
5503 auto underlyingType = tdnDecl.getUnderlyingType().getCanonicalType();
5504 if (
const clang::TagType* TT
5505 = llvm::dyn_cast<clang::TagType>(underlyingType.getTypePtr())) {
5506 if (clang::NamedDecl* ND = TT->getDecl()) {
5507 if (!ND->getIdentifier()) {
5521 if (underlyingName.find(
">::") != std::string::npos)
5524 buffer=
"typedef "+underlyingName+
" "+buffer+
";";
5536 auto& ctxt = tdnDecl.getASTContext();
5537 auto immediatelyUnderlyingType = underlyingType.getSingleStepDesugaredType(ctxt);
5539 if (
auto underlyingTdnTypePtr = llvm::dyn_cast<clang::TypedefType>(immediatelyUnderlyingType.getTypePtr())){
5540 std::string tdnFwdDecl;
5541 auto underlyingTdnDeclPtr = underlyingTdnTypePtr->getDecl();
5546 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(tdnFwdDecl).second)
5547 fwdDeclString+=tdnFwdDecl;
5548 }
else if (
auto CXXRcdDeclPtr = immediatelyUnderlyingType->getAsCXXRecordDecl()){
5549 std::string classFwdDecl;
5551 std::cout <<
"Typedef " << tdnDecl.getNameAsString() <<
" hides a class: "
5552 << CXXRcdDeclPtr->getNameAsString() << std::endl;
5561 if (!fwdDeclSetPtr || fwdDeclSetPtr->insert(classFwdDecl).second)
5562 fwdDeclString+=classFwdDecl;
5565 fwdDeclString+=buffer;
5577 std::string& valAsString,
5578 const clang::PrintingPolicy& ppolicy)
5580 auto defArgExprPtr = par.getDefaultArg();
5581 auto& ctxt = par.getASTContext();
5582 if(!defArgExprPtr->isEvaluatable(ctxt)){
5586 auto defArgType = par.getType();
5589 if (defArgType->isBooleanType()){
5591 defArgExprPtr->EvaluateAsBooleanCondition (
result,ctxt);
5592 valAsString=std::to_string(
result);
5597 if (defArgType->isIntegerType()){
5598 clang::Expr::EvalResult evalResult;
5599 defArgExprPtr->EvaluateAsInt(evalResult, ctxt);
5600 llvm::APSInt
result = evalResult.Val.getInt();
5601 auto uintVal = *
result.getRawData();
5602 if (
result.isNegative()){
5603 long long int intVal=uintVal*-1;
5604 valAsString=std::to_string(intVal);
5606 valAsString=std::to_string(uintVal);
5613 llvm::raw_string_ostream rso(valAsString);
5614 defArgExprPtr->printPretty(rso,
nullptr,ppolicy);
5615 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)
static Roo_reg_AGKInteg1D instance
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
static void indent(ostringstream &buf, int indent_level)
static bool RecurseKeepNParams(clang::TemplateArgument &normTArg, const clang::TemplateArgument &tArg, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, const clang::ASTContext &astCtxt)
static clang::SourceLocation getFinalSpellingLoc(clang::SourceManager &sourceManager, clang::SourceLocation sourceLoc)
const clang::DeclContext * GetEnclosingSpace(const clang::RecordDecl &cl)
bool IsTemplate(const clang::Decl &cl)
static void KeepNParams(clang::QualType &normalizedType, const clang::QualType &vanillaType, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
This function allows to manipulate the number of arguments in the type of a template specialisation.
static void CreateNameTypeMap(const clang::CXXRecordDecl &cl, ROOT::MembersTypeMap_t &nameType)
Create the data member name-type map for given class.
const clang::CXXMethodDecl * GetMethodWithProto(const clang::Decl *cinfo, const char *method, const char *proto, const cling::Interpreter &interp, bool diagnose)
int dumpDeclForAssert(const clang::Decl &D, const char *commentStart)
static void replaceEnvVars(const char *varname, std::string &txt)
Reimplementation of TSystem::ExpandPathName() that cannot be used from TMetaUtils.
static bool areEqualValues(const clang::TemplateArgument &tArg, const clang::NamedDecl &tPar)
std::cout << "Are equal values?\n";
ROOT::TMetaUtils::TNormalizedCtxtImpl TNCtxtFullQual
static bool isTypeWithDefault(const clang::NamedDecl *nDecl)
Check if this NamedDecl is a template parameter with a default argument.
static int TreatSingleTemplateArg(const clang::TemplateArgument &arg, std::string &argFwdDecl, const cling::Interpreter &interpreter, bool acceptStl=false)
static bool areEqualTypes(const clang::TemplateArgument &tArg, llvm::SmallVectorImpl< clang::TemplateArgument > &preceedingTArgs, const clang::NamedDecl &tPar, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
static bool hasSomeTypedefSomewhere(const clang::Type *T)
return
Invalidate stored TCling state for declarations included in transaction ‘T’.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
const std::string & GetPathSeparator()
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
void WriteSchemaList(std::list< SchemaRuleMap_t > &rules, const std::string &listName, std::ostream &output)
Write schema rules.
std::map< std::string, ROOT::Internal::TSchemaType > MembersTypeMap_t
void WriteReadRuleFunc(SchemaRuleMap_t &rule, int index, std::string &mappedName, MembersTypeMap_t &members, std::ostream &output)
Write the conversion function for Read rule, the function name is being written to rule["funcname"].
R__EXTERN SchemaRuleClassMap_t gReadRules
bool HasValidDataMembers(SchemaRuleMap_t &rule, MembersTypeMap_t &members, std::string &error_string)
Check if given rule contains references to valid data members.
void WriteReadRawRuleFunc(SchemaRuleMap_t &rule, int index, std::string &mappedName, MembersTypeMap_t &members, std::ostream &output)
Write the conversion function for ReadRaw rule, the function name is being written to rule["funcname"...
R__EXTERN SchemaRuleClassMap_t gReadRawRules
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
std::string GetLong64_Name(const char *original)
Replace 'long long' and 'unsigned long long' by 'Long64_t' and 'ULong64_t'.
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
char * DemangleName(const char *mangled_name, int &errorCode)
std::string GetNameForIO(const std::string &templateInstanceName, TClassEdit::EModType mode=TClassEdit::kNone, bool *hasChanged=nullptr)
bool IsSTLBitset(const char *type)
Return true is the name is std::bitset<number> or bitset<number>
constexpr Double_t C()
Velocity of light in .
void ShortType(std::string &answer, int mode)
Return the absolute type of typeDesc into the string answ.