24#include <unordered_set>
27#include "RConfigure.h"
36#include "clang/AST/ASTContext.h"
37#include "clang/AST/Attr.h"
38#include "clang/AST/CXXInheritance.h"
39#include "clang/AST/Decl.h"
40#include "clang/AST/DeclTemplate.h"
41#include "clang/AST/Mangle.h"
42#include "clang/AST/Type.h"
43#include "clang/AST/TypeVisitor.h"
44#include "clang/Frontend/CompilerInstance.h"
45#include "clang/Lex/HeaderSearch.h"
46#include "clang/Lex/ModuleMap.h"
47#include "clang/Lex/Preprocessor.h"
48#include "clang/Lex/PreprocessorOptions.h"
50#include "clang/Sema/Lookup.h"
51#include "clang/Sema/Sema.h"
52#include "clang/Sema/SemaDiagnostic.h"
54#include "cling/Interpreter/LookupHelper.h"
55#include "cling/Interpreter/Transaction.h"
56#include "cling/Interpreter/Interpreter.h"
57#include "cling/Utils/AST.h"
58#include "cling/Interpreter/InterpreterAccessRAII.h"
60#include "llvm/Support/Path.h"
61#include "llvm/Support/FileSystem.h"
66#define strncasecmp _strnicmp
86 using DeclsCont_t = TNormalizedCtxt::Config_t::SkipCollection;
103 bool replace =
false);
114 clang::NestedNameSpecifier*
scope,
117 if (!
scope)
return nullptr;
140static bool CheckDefinition(
const clang::CXXRecordDecl *cl,
const clang::CXXRecordDecl *context)
142 if (!cl->hasDefinition()) {
145 "Missing definition for class %s, please #include its header in the header of %s\n",
146 cl->getName().str().c_str(), context->getName().str().c_str());
149 "Missing definition for class %s\n",
150 cl->getName().str().c_str());
163 clang::NestedNameSpecifier *
scope,
166 if (!
scope)
return nullptr;
188 const clang::BuiltinType *
builtin = llvm::dyn_cast<clang::BuiltinType>(
type->getCanonicalTypeInternal().getTypePtr());
208 clang::ASTContext &
C = cl.getASTContext();
209 clang::DeclarationName
DName = &
C.Idents.get(
what);
210 auto R = cl.lookup(
DName);
211 for (
const clang::NamedDecl *D :
R)
223 clang::LookupResult
R(
SemaR,
DName, clang::SourceLocation(),
224 clang::Sema::LookupOrdinaryName,
225 RedeclarationKind::ForExternalRedeclaration);
226 SemaR.LookupInSuper(
R, &
const_cast<clang::CXXRecordDecl&
>(cl));
229 return llvm::dyn_cast<const clang::FieldDecl>(
R.getFoundDecl());
235 ? cling::LookupHelper::WithDiagnostics
236 : cling::LookupHelper::NoDiagnostics;
243namespace TMetaUtils {
252 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
253 "Tring to specify a number of template arguments to keep for a null pointer. Exiting without assigning any value.\n");
257 const clang::ClassTemplateDecl*
canTempl =
templ->getCanonicalDecl();
262 const std::string
i_str (std::to_string(i));
264 Error(
"TNormalizedCtxt::AddTemplAndNargsToKeep",
265 "Tring to specify for template %s %s arguments to keep, while before this number was %s\n",
266 canTempl->getNameAsString().c_str(),
279 const clang::ClassTemplateDecl*
constTempl =
templ->getCanonicalDecl();
330 std::unique_ptr<clang::MangleContext>
mangleCtx(
rDecl->getASTContext().createMangleContext());
334 if (
const clang::TypeDecl*
TD = llvm::dyn_cast<clang::TypeDecl>(
rDecl)) {
335 mangleCtx->mangleCXXRTTI(clang::QualType(
TD->getTypeForDecl(), 0),
sstr);
361 "Demangled typeinfo name '%s' does not contain `RTTI Type Descriptor'\n",
365 "Demangled typeinfo name '%s' does not start with 'typeinfo for'\n",
382 const clang::RecordDecl *
decl,
413 const clang::RecordDecl *
decl,
444 "Could not remove the requested template arguments.\n");
455 const clang::RecordDecl *
decl,
491 const clang::RecordDecl *
decl,
540 fCheckInClassTable(CheckInClassTable),
554 if (
tname.empty())
return false;
579 if (!
dest.isNull() && (
dest != t)) {
599 if (!
dest.isNull() && (
dest != t) &&
621 const clang::NamespaceDecl *
nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(
scope);
634 if (
tname.empty())
return false;
666 clang::PrintingPolicy
policy(
fInterpreter->getCI()->getASTContext().getPrintingPolicy());
667 policy.SuppressTagKeyword =
true;
672 policy.SuppressUnwrittenScope =
true;
685 for(
unsigned int i = 1; i<
result.length(); ++i) {
697 }
else if ( (i+1) <
result.length() &&
735 clang::QualType
toSkip =
lh.findType(
name, cling::LookupHelper::WithDiagnostics);
736 if (
const clang::Type* T =
toSkip.getTypePtr()) {
737 const clang::TypedefType *
tt = llvm::dyn_cast<clang::TypedefType>(T);
739 clang::Decl* D =
tt->getDecl();
740 fConfig.m_toSkip.insert(D);
742 clang::QualType
canon =
toSkip->getCanonicalTypeInternal();
743 fConfig.m_toReplace.insert(std::make_pair(
canon.getTypePtr(),T));
745 fTypeWithAlternative.insert(T);
758 keepTypedef(
lh,
"Double32_t");
759 keepTypedef(
lh,
"Float16_t");
760 keepTypedef(
lh,
"Long64_t",
true);
761 keepTypedef(
lh,
"ULong64_t",
true);
763 clang::QualType
toSkip =
lh.findType(
"string", cling::LookupHelper::WithDiagnostics);
765 if (
const clang::TypedefType* TT
766 = llvm::dyn_cast_or_null<clang::TypedefType>(
toSkip.getTypePtr()))
767 fConfig.m_toSkip.insert(TT->getDecl());
769 toSkip =
lh.findType(
"std::string", cling::LookupHelper::WithDiagnostics);
771 if (
const clang::TypedefType* TT
772 = llvm::dyn_cast_or_null<clang::TypedefType>(
toSkip.getTypePtr()))
773 fConfig.m_toSkip.insert(TT->getDecl());
775 clang::QualType
canon =
toSkip->getCanonicalTypeInternal();
776 fConfig.m_toReplace.insert(std::make_pair(
canon.getTypePtr(),
toSkip.getTypePtr()));
787 return (cl.getKind() == clang::Decl::ClassTemplatePartialSpecialization
788 || cl.getKind() == clang::Decl::ClassTemplateSpecialization);
795 const cling::Interpreter&
interp)
797 clang::Sema* S = &
interp.getSema();
798 const clang::NamedDecl*
ND = cling::utils::Lookup::Named(S,
name, cl);
799 if (
ND == (clang::NamedDecl*)-1)
800 return (clang::FunctionDecl*)-1;
801 return llvm::dyn_cast_or_null<clang::FunctionDecl>(
ND);
807const clang::CXXRecordDecl *
811 const cling::LookupHelper&
lh =
interp.getLookupHelper();
814 const clang::CXXRecordDecl *
result
815 = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
822 result = llvm::dyn_cast_or_null<clang::CXXRecordDecl>
833 clang::QualType
qType(cl->getTypeForDecl(),0);
841 clang::Sema& S =
interp.getCI()->getSema();
844 cling::Interpreter::PushTransactionRAII
RAII(
const_cast<cling::Interpreter*
>(&
interp));
845 return S.RequireCompleteType(
Loc, Type, clang::diag::err_incomplete_type);
851 const clang::CXXRecordDecl *context,
const cling::Interpreter &
interp)
857 if (!cl->getDefinition() || !cl->isCompleteDefinition()) {
865 if (!base->hasDefinition()) {
869 return cl->isDerivedFrom(base);
881 const clang::NamedDecl *base
885 return IsBase(
CRD, llvm::dyn_cast<clang::CXXRecordDecl>( base ),
886 llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext()),
interp);
895 const clang::QualType &
qti,
897 const cling::Interpreter &
interp,
905 kBIT_ISSTRING = 0x40000000,
912 const clang::Type &
ti( *
qti.getTypePtr() );
935 if (
tiName ==
"string")
kase |= kBIT_ISSTRING;
936 if (
tiName ==
"string*")
kase |= kBIT_ISSTRING;
940 tcl =
" internal error in rootcling ";
965 <<
" R__b >> readtemp;" << std::endl
966 <<
" " <<
R__t <<
" = static_cast<" <<
tiName <<
">(readtemp);" << std::endl;
978 finalString <<
" if (R__b.GetInfo() && R__b.GetInfo()->GetOldVersion()<=3) {" << std::endl;
980 finalString <<
" R__ASSERT(0);// " <<
objType <<
" is abstract. We assume that older file could not be produced using this streaming method." << std::endl;
983 <<
" " <<
R__t <<
"->Streamer(R__b);" << std::endl;
986 <<
" " <<
R__t <<
" = (" <<
tiName <<
")R__b.ReadObjectAny(" <<
tcl <<
");" << std::endl
987 <<
" }" << std::endl;
993 <<
" R__str.Streamer(R__b);" << std::endl
994 <<
" " <<
R__t <<
" = R__str.Data();}" << std::endl;
1000 <<
" R__str.Streamer(R__b);" << std::endl
1001 <<
" " <<
R__t <<
" = new string(R__str.Data());}" << std::endl;
1005 if (!
R__t)
return 1;
1010 if (!
R__t)
return 1;
1021 if (!
R__t)
return 0;
1026 if (!
R__t)
return 0;
1028 finalString <<
" R__b >> *reinterpret_cast<Int_t*>(ptr_enum); }" << std::endl;
1033 if (!
R__t)
return 0;
1038 if (!
R__t)
return 1;
1043 if (!
R__t)
return 0;
1044 finalString <<
" {TString R__str(" <<
R__t <<
".c_str());" << std::endl
1045 <<
" R__str.Streamer(R__b);};" << std::endl;
1049 if (!
R__t)
return 0;
1050 finalString <<
" {TString R__str(" <<
R__t <<
"->c_str());" << std::endl
1051 <<
" R__str.Streamer(R__b);}" << std::endl;
1055 if (!
R__t)
return 1;
1060 if (!
R__t)
return 1;
1073 clang::CXXRecordDecl*
ncCl =
const_cast<clang::CXXRecordDecl*
>(cl);
1076 cling::Interpreter::PushTransactionRAII
clingRAII(
const_cast<cling::Interpreter*
>(&
interpreter));
1079 if (
Ctor->getAccess() == clang::AS_public && !
Ctor->isDeleted()) {
1097 const cling::LookupHelper&
lh =
interpreter.getLookupHelper();
1106 return EIOCtorCategory::kAbsent;
1109 cling::Interpreter::PushTransactionRAII
clingRAII(
const_cast<cling::Interpreter*
>(&
interpreter));
1110 for (
auto iter = cl->ctor_begin(), end = cl->ctor_end(); iter != end; ++iter)
1112 if ((iter->getAccess() != clang::AS_public) || (iter->getNumParams() != 1))
1116 clang::QualType
argType((*iter->param_begin())->getType());
1120 if (
argType->isPointerType()) {
1123 }
else if (
argType->isReferenceType()) {
1130 const clang::CXXRecordDecl *
argDecl =
argType->getAsCXXRecordDecl();
1137 std::string
clarg(
"class ");
1144 return EIOCtorCategory::kAbsent;
1157 if (!
ioctortype.GetType() && (!arg || !arg[0])) {
1171 const cling::Interpreter &
interp,
1174 const clang::FunctionDecl*
funcD
1176 diagnose ? cling::LookupHelper::WithDiagnostics
1177 : cling::LookupHelper::NoDiagnostics);
1179 return llvm::dyn_cast<const clang::CXXMethodDecl>(
funcD);
1188 namespace TMetaUtils {
1191 const cling::LookupHelper&
lh =
interp.getLookupHelper();
1210 const cling::Interpreter &
interp)
1212 if (cl->isAbstract())
return false;
1218 if (EIOCtorCategory::kAbsent ==
ioCtorCat)
1228 if (EIOCtorCategory::kIOPtrType ==
ioCtorCat) {
1230 }
else if (EIOCtorCategory::kIORefType ==
ioCtorCat) {
1234 arg +=
")nullptr )";
1237 const clang::CXXMethodDecl *
method
1239 cling::LookupHelper::NoDiagnostics);
1240 if (
method &&
method->getAccess() != clang::AS_public) {
1254 const cling::Interpreter&
interp)
1256 if (!cl)
return false;
1258 if (cl->hasUserDeclaredDestructor()) {
1260 cling::Interpreter::PushTransactionRAII
clingRAII(
const_cast<cling::Interpreter*
>(&
interp));
1261 clang::CXXDestructorDecl *
dest = cl->getDestructor();
1263 return (
dest->getAccess() == clang::AS_public);
1277 const cling::Interpreter &
interp,
1280 const clang::CXXMethodDecl *
method
1282 diagnose ? cling::LookupHelper::WithDiagnostics
1283 : cling::LookupHelper::NoDiagnostics);
1284 return (
method &&
method->getAccess() == clang::AS_public);
1295 const char *
proto =
"TDirectory*";
1296 const char *
name =
"DirectoryAutoAdd";
1310 const char *
proto =
"TCollection*,TFileMergeInfo*";
1311 const char *
name =
"Merge";
1324 const char *
proto =
"TCollection*";
1325 const char *
name =
"Merge";
1340 const char *
proto =
"TFileMergeInfo*";
1341 const char *
name =
"ResetAfterMerge";
1351 const clang::CXXRecordDecl*
clxx,
1352 const cling::Interpreter &
interp,
1355 static const char *
proto =
"TBuffer&";
1357 const clang::CXXMethodDecl *
method
1359 cling::LookupHelper::NoDiagnostics);
1370 const clang::CXXRecordDecl*
clxx,
1371 const cling::Interpreter &
interp,
1374 static const char *
proto =
"TBuffer&,TClass*";
1376 const clang::CXXMethodDecl *
method
1378 cling::LookupHelper::NoDiagnostics);
1443 llvm::raw_string_ostream stream(
qual_name);
1444 clang::PrintingPolicy
policy( cl.getASTContext().getPrintingPolicy() );
1445 policy.SuppressTagKeyword =
true;
1446 policy.SuppressUnwrittenScope =
true;
1448 cl.getNameForDiagnostic(stream,
policy,
true);
1504 std::stringstream
dims;
1507 const clang::ASTContext&
astContext = cl.getASTContext();
1510 for(clang::RecordDecl::field_iterator
field_iter = cl.field_begin(), end = cl.field_end();
1524 const clang::ConstantArrayType *
arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
fieldType.getTypePtr());
1526 dims <<
"[" <<
arrayType->getSize().getLimitedValue() <<
"]";
1528 arrayType = llvm::dyn_cast<clang::ConstantArrayType>(
arrayType->getArrayElementTypeNoTypeQual());
1538 for(clang::CXXRecordDecl::base_class_const_iterator iter = cl.bases_begin(), end = cl.bases_end();
1541 std::string
basename( iter->getType()->getAsCXXRecordDecl()->getNameAsString() );
1551 const cling::Interpreter &
interp,
1555 diagnose ? cling::LookupHelper::WithDiagnostics
1556 : cling::LookupHelper::NoDiagnostics);
1615 while (llvm::isa<clang::PointerType>(
instanceType.getTypePtr())
1616 || llvm::isa<clang::ReferenceType>(
instanceType.getTypePtr()))
1621 const clang::ElaboratedType* etype
1622 = llvm::dyn_cast<clang::ElaboratedType>(
instanceType.getTypePtr());
1624 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
1638 if (
clxx &&
clxx->getTemplateSpecializationKind() != clang::TSK_Undeclared) {
1640 const clang::TemplateSpecializationType*
TST
1641 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
instanceType.getTypePtr());
1648 for (
const clang::TemplateArgument &
TA :
TST->template_arguments()) {
1649 if (
TA.getKind() == clang::TemplateArgument::Type) {
1661 const cling::Interpreter &
interp,
1664 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
1665 if (!
clxx ||
clxx->getTemplateSpecializationKind() == clang::TSK_Undeclared)
return false;
1668 cling::LookupHelper::WithDiagnostics);
1682 clang::AnnotateAttr*
annAttr = clang::dyn_cast<clang::AnnotateAttr>(
attribute);
1725 for (clang::Decl::attr_iterator
attrIt =
decl.attr_begin();
1727 clang::AnnotateAttr*
annAttr = clang::dyn_cast<clang::AnnotateAttr>(*
attrIt);
1731 std::pair<llvm::StringRef,llvm::StringRef> split =
attribute.split(propNames::separator.c_str());
1732 if (split.first !=
propName.c_str())
continue;
1748 for (clang::Decl::attr_iterator
attrIt =
decl.attr_begin();
1750 clang::AnnotateAttr*
annAttr = clang::dyn_cast<clang::AnnotateAttr>(*
attrIt);
1754 std::pair<llvm::StringRef,llvm::StringRef> split =
attribute.split(propNames::separator.c_str());
1755 if (split.first !=
propName.c_str())
continue;
1757 return split.second.getAsInteger(10,
propValue);
1768 const clang::CXXRecordDecl *
decl,
1769 const cling::Interpreter &
interp,
1778 std::string
csymbol = classname;
1792 bool isStd = TMetaUtils::IsStdClass(*
decl);
1793 const cling::LookupHelper&
lh =
interp.getLookupHelper();
1803 <<
" static void " <<
mappedname.c_str() <<
"_TClassManip(TClass*);\n";
1821 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";
1824 finalString <<
" static void directoryAutoAdd_" <<
mappedname.c_str() <<
"(void *obj, TDirectory *dir);" <<
"\n";
1827 finalString <<
" static void streamer_" <<
mappedname.c_str() <<
"(TBuffer &buf, void *obj);" <<
"\n";
1830 finalString <<
" static void conv_streamer_" <<
mappedname.c_str() <<
"(TBuffer &buf, void *obj, const TClass*);" <<
"\n";
1833 finalString <<
" static Long64_t merge_" <<
mappedname.c_str() <<
"(void *obj, TCollection *coll,TFileMergeInfo *info);" <<
"\n";
1836 finalString <<
" static void reset_" <<
mappedname.c_str() <<
"(void *obj, TFileMergeInfo *info);" <<
"\n";
1855 finalString <<
"\n // Schema evolution read functions\n";
1856 std::list<ROOT::SchemaRuleMap_t>::iterator
rIt =
rulesIt1->second.fRules.
begin();
1874 if(
rIt->find(
"code" ) !=
rIt->
end() ) {
1890 finalString <<
"\n // Schema evolution read raw functions\n";
1891 std::list<ROOT::SchemaRuleMap_t>::iterator
rIt =
rulesIt2->second.fRules.
begin();
1917 finalString <<
"\n" <<
" // Function generating the singleton type initializer" <<
"\n";
1919 finalString <<
" static TGenericClassInfo *GenerateInitInstanceLocal(const " <<
csymbol <<
"*)" <<
"\n" <<
" {" <<
"\n";
1925 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TInstrumentedIsAProxy< " <<
csymbol <<
" >(nullptr);" <<
"\n";
1928 finalString <<
" static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(" <<
csymbol <<
"));" <<
"\n";
1930 finalString <<
" static ::ROOT::TGenericClassInfo " <<
"\n" <<
" instance(\"" << classname.c_str() <<
"\", ";
1943 static const char *
versionFunc =
"GetClassVersion";
1947 std::string
proto = classname +
"*";
1948 const clang::Decl*
ctxt = llvm::dyn_cast<clang::Decl>((*cl).getDeclContext());
1951 interp, cling::LookupHelper::NoDiagnostics);
1970 for (
unsigned int i=0; i<
filename.length(); i++) {
1975 <<
"," <<
"\n" <<
" typeid(" <<
csymbol
1976 <<
"), ::ROOT::Internal::DefineBehavior(ptr, ptr)," <<
"\n" <<
" ";
1993 <<
" sizeof(" <<
csymbol <<
"), alignof(" <<
csymbol <<
") );" <<
"\n";
2000 finalString <<
" instance.SetDelete(&delete_" <<
mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDeleteArray(&deleteArray_" <<
mappedname.c_str() <<
");" <<
"\n" <<
" instance.SetDestructor(&destruct_" <<
mappedname.c_str() <<
");" <<
"\n";
2003 finalString <<
" instance.SetDirectoryAutoAdd(&directoryAutoAdd_" <<
mappedname.c_str() <<
");" <<
"\n";
2011 finalString <<
" instance.SetConvStreamerFunc(&conv_streamer_" <<
mappedname.c_str() <<
");" <<
"\n";
2020 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
"Pushback" <<
"<Internal::TStdBitsetHelper< " << classname.c_str() <<
" > >()));" <<
"\n";
2023 }
else if (
stl != 0 &&
2026 int idx = classname.find(
"<");
2057 finalString <<
" \"Class with alignment strictly greater than 4096 are currently not supported in "
2058 "CollectionProxy. \"\n";
2059 finalString <<
" \"Please report this case to the developers\");\n";
2060 finalString <<
" instance.AdoptCollectionProxyInfo(TCollectionProxyInfo::Generate(TCollectionProxyInfo::" <<
methodTCP <<
"< " <<
classNameForIO.c_str() <<
" >()));" <<
"\n";
2070 finalString <<
"\n" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2077 finalString <<
"\n" <<
" instance.AdoptAlternate(::ROOT::AddClassAlternate(\""
2095 finalString <<
"\n" <<
" ::ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
2099 finalString <<
"\n" <<
" // the io read rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrules(" <<
rulesIt1->second.size() <<
");" <<
"\n";
2101 finalString <<
" instance.SetReadRules( readrules );" <<
"\n";
2102 rulesIt1->second.fGenerated =
true;
2106 finalString <<
"\n" <<
" // the io read raw rules" <<
"\n" <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrawrules(" <<
rulesIt2->second.size() <<
");" <<
"\n";
2108 finalString <<
" instance.SetReadRawRules( readrawrules );" <<
"\n";
2109 rulesIt2->second.fGenerated =
true;
2112 finalString <<
" return &instance;" <<
"\n" <<
" }" <<
"\n";
2116 finalString <<
" TGenericClassInfo *GenerateInitInstance(const " <<
csymbol <<
"*)" <<
"\n" <<
" {\n return GenerateInitInstanceLocal(static_cast<" <<
csymbol <<
"*>(nullptr));\n }" <<
"\n";
2119 finalString <<
" // Static variable to force the class initialization" <<
"\n";
2123 finalString <<
" static ::ROOT::TGenericClassInfo *_R__UNIQUE_DICT_(Init) = GenerateInitInstanceLocal(static_cast<const " <<
csymbol <<
"*>(nullptr)); R__UseDummy(_R__UNIQUE_DICT_(Init));" <<
"\n";
2126 finalString <<
"\n" <<
" // Dictionary for non-ClassDef classes" <<
"\n"
2127 <<
" static TClass *" <<
mappedname <<
"_Dictionary() {\n"
2128 <<
" TClass* theClass ="
2129 <<
"::ROOT::GenerateInitInstanceLocal(static_cast<const " <<
csymbol <<
"*>(nullptr))->GetClass();\n"
2130 <<
" " <<
mappedname <<
"_TClassManip(theClass);\n";
2141 if (
decl->hasAttrs()){
2143 for (clang::Decl::attr_iterator
attrIt =
decl->attr_begin();
2160 manipString+=
" theClass->CreateAttributeMap();\n";
2161 manipString+=
" TDictAttributeMap* attrMap( theClass->GetAttributeMap() );\n";
2172 if (!(!(*internalDeclIt)->isImplicit()
2193 TMetaUtils::Error(
nullptr,
"Cannot convert field declaration to clang::NamedDecl");
2209 if (
attrName == propNames::comment ||
2211 attrName == propNames::ioname )
continue;
2236 finalString <<
"} // end of namespace ROOT" <<
"\n" <<
"\n";
2241 const cling::Interpreter &
interp)
2245 const clang::Type *
typeptr =
nullptr;
2246 const clang::CXXRecordDecl *
target =
2251 std::string
rule{
nRules > 1 ?
"rules" :
"rule"};
2252 std::string
verb{
nRules > 1 ?
"were" :
"was"};
2270 finalString <<
"\n // Schema evolution read functions\n";
2271 std::list<ROOT::SchemaRuleMap_t>::iterator
rIt =
rulesIt1.second.fRules.
begin();
2312 finalString <<
" // Registration Schema evolution read functions\n";
2316 <<
" ::ROOT::Internal::TSchemaHelper* rule;" <<
"\n";
2325 finalString <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrules(" <<
rulesIt1->second.size()
2328 finalString <<
" TClass::RegisterReadRules(TSchemaRule::kReadRule, \"" <<
name
2329 <<
"\", std::move(readrules));\n";
2330 rulesIt1->second.fGenerated =
true;
2335 finalString <<
" std::vector<::ROOT::Internal::TSchemaHelper> readrawrules(" <<
rulesIt2->second.size()
2338 finalString <<
" TClass::RegisterReadRules(TSchemaRule::kReadRawRule, \"" <<
name
2339 <<
"\", std::move(readrawrules));\n";
2340 rulesIt2->second.fGenerated =
true;
2360 const clang::CXXRecordDecl *cl)
2370 auto ctxt = cl->getEnclosingNamespaceContext();
2375 const clang::NamedDecl *
namedCtxt = llvm::dyn_cast<clang::NamedDecl>(
ctxt);
2377 const clang::NamespaceDecl *
nsdecl = llvm::dyn_cast<clang::NamespaceDecl>(
namedCtxt);
2392 const clang::DeclContext *
ctxt = cl.getDeclContext();
2393 while(
ctxt && !
ctxt->isNamespace()) {
2414 const clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(
ctxt);
2420 out <<
"namespace " << ns->getNameAsString() <<
" {" << std::endl;
2439 clang::TemplateSpecializationKind kind = cl->getTemplateSpecializationKind();
2440 if (kind == clang::TSK_Undeclared ) {
2443 }
else if (kind == clang::TSK_ExplicitSpecialization) {
2458 const char *
proto =
"size_t";
2465 cling::LookupHelper::NoDiagnostics);
2469 cling::LookupHelper::NoDiagnostics);
2471 const clang::DeclContext *
ctxtnew =
nullptr;
2507 const clang::CXXRecordDecl*
clnew = llvm::dyn_cast<clang::CXXRecordDecl>(
ctxtnew);
2554 const clang::CXXRecordDecl *
decl,
2555 const cling::Interpreter &
interp,
2579 classname.insert(0,
"::");
2587 finalString <<
" // Wrappers around operator new" <<
"\n";
2588 finalString <<
" static void *new_" <<
mappedname.c_str() <<
"(void *p) {" <<
"\n" <<
" return p ? ";
2595 finalString <<
"::new(static_cast<::ROOT::Internal::TOperatorNewHelper*>(p)) ";
2600 finalString <<
"new " << classname.c_str() << args <<
";" <<
"\n";
2615 finalString <<
"::new(static_cast<::ROOT::Internal::TOperatorNewHelper*>(p)) ";
2629 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";
2633 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";
2637 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";
2641 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";
2645 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";
2647 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";
2651 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";
2653 finalString <<
"} // end of namespace ROOT for class " << classname.c_str() <<
"\n" <<
"\n";
2660 const cling::Interpreter &
interp,
2671 const clang::CXXRecordDecl *
clxx = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
2675 for(clang::CXXRecordDecl::base_class_const_iterator iter =
clxx->bases_begin(), end =
clxx->bases_end();
2681 Internal::RStl::Instance().GenerateTClassFor( iter->getType(),
interp,
normCtxt);
2686 for(clang::RecordDecl::field_iterator
field_iter =
clxx->field_begin(), end =
clxx->field_end();
2718 const clang::Type *
rawtype =
m.getType()->getCanonicalTypeInternal().getTypePtr();
2734 const clang::CXXRecordDecl*
CRD = llvm::dyn_cast<clang::CXXRecordDecl>(cl);
2746 if (
funcCV == (clang::FunctionDecl*)-1)
return 1;
2761 using res_t = std::pair<bool, int>;
2763 const clang::CompoundStmt*
FuncBody
2764 = llvm::dyn_cast_or_null<clang::CompoundStmt>(
funcCV->getBody());
2766 return res_t{
false, -1};
2771 return res_t{
false, -1};
2773 const clang::ReturnStmt*
RetStmt
2774 = llvm::dyn_cast<clang::ReturnStmt>(
FuncBody->body_back());
2776 return res_t{
false, -1};
2788 return res_t{
false, -1};
2796 return TMetaUtils::IsSTLCont(*
annotated.GetRecordDecl());
2804 clang::QualType
type =
m.getType();
2807 if (
decl)
return TMetaUtils::IsSTLCont(*
decl);
2816 clang::QualType
type = base.getType();
2819 if (
decl)
return TMetaUtils::IsSTLCont(*
decl);
2829 const std::function<
void(
const clang::Module::Header &)> &
closure,
2837 llvm::SetVector<const clang::Module *>
modules;
2839 for (
size_t i = 0; i <
modules.size(); ++i) {
2840 const clang::Module *M =
modules[i];
2841 for (
const clang::Module *
subModule : M->submodules())
2845 for (
const clang::Module *
m :
modules) {
2847 for (clang::Module *
used :
m->DirectUses) {
2853 for (
auto HK : {clang::Module::HK_Normal, clang::Module::HK_Textual, clang::Module::HK_Private,
2854 clang::Module::HK_PrivateTextual}) {
2871 static char t[4096];
2872 static const char*
constwd =
"const ";
2881 if (
lev==0 && *s==
'*')
continue;
2887 if (
lev==0 && *s==
' ' && *(s+1)!=
'*') {
p = t;
continue;}
2888 if (
p - t > (
long)
sizeof(t)) {
2889 printf(
"ERROR (rootcling): type name too long for StortTypeName: %s\n",
2902 const cling::Interpreter&
interp)
2907 if (!comment.empty() && comment[0] ==
'!')
2910 clang::QualType
type =
m.getType();
2912 if (
type->isReferenceType()) {
2917 std::string
mTypeName =
type.getAsString(
m.getASTContext().getPrintingPolicy());
2929 const clang::Type *
rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
2931 if (
rawtype->isPointerType()) {
2945 const clang::CXXRecordDecl *
cxxdecl =
rawtype->getAsCXXRecordDecl();
2962 const clang::Type *
rawtype =
m.getType().getTypePtr();
2986 return rawtype->getAsCXXRecordDecl();
2995 const cling::Interpreter &
interp,
3001 const clang::CXXRecordDecl*
decl = llvm::dyn_cast<clang::CXXRecordDecl>(cl.
GetRecordDecl());
3003 if (!
decl || !
decl->isCompleteDefinition()) {
3007 std::string fullname;
3021 ROOT::TMetaUtils::Info(
nullptr,
"Class %s: Do not generate Streamer() [*** custom streamer ***]\n",fullname.c_str());
3046 const clang::ASTContext&
Ctx =
interpreter.getCI()->getASTContext();
3052 if (llvm::isa<clang::PointerType>(
instanceType.getTypePtr())) {
3066 if (llvm::isa<clang::ReferenceType>(
instanceType.getTypePtr())) {
3086 clang::NestedNameSpecifier *prefix =
nullptr;
3088 const clang::ElaboratedType* etype
3089 = llvm::dyn_cast<clang::ElaboratedType>(
instanceType.getTypePtr());
3094 instanceType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3100 const clang::TemplateSpecializationType*
TST
3101 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
instanceType.getTypePtr());
3103 const clang::ClassTemplateSpecializationDecl*
TSTdecl
3104 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(
instanceType.getTypePtr()->getAsCXXRecordDecl());
3120 clang::TemplateDecl *
Template =
TSTdecl->getSpecializedTemplate()->getMostRecentDecl();
3121 clang::TemplateParameterList *Params =
Template->getTemplateParameters();
3128 llvm::SmallVector<clang::TemplateArgument, 4>
desArgs;
3129 llvm::SmallVector<clang::TemplateArgument, 4>
canonArgs;
3143 if (
I->getKind() == clang::TemplateArgument::Template) {
3150 clang::NamespaceDecl* ns = clang::dyn_cast<clang::NamespaceDecl>(
declCtxt);
3151 clang::NestedNameSpecifier*
nns;
3153 nns = cling::utils::TypeName::CreateNestedNameSpecifier(
Ctx, ns);
3154 }
else if (clang::TagDecl*
TD = llvm::dyn_cast<clang::TagDecl>(
declCtxt)) {
3155 nns = cling::utils::TypeName::CreateNestedNameSpecifier(
Ctx,
TD,
false );
3162 if (clang::UsingShadowDecl *
USD =
templateName.getAsUsingShadowDecl())
3172 if (
I->getKind() != clang::TemplateArgument::Type) {
3177 clang::QualType
SubTy =
I->getAsType();
3199 if (
templateArg.getKind() != clang::TemplateArgument::Type) {
3208 clang::TemplateTypeParmDecl *
TTP = llvm::dyn_cast<clang::TemplateTypeParmDecl>(*
Param);
3211 cling::Interpreter::PushTransactionRAII
clingRAII(
const_cast<cling::Interpreter*
>(&
interpreter));
3213 clang::TemplateArgumentLoc
ArgType = S.SubstDefaultTemplateArgumentIfAvailable(
3223 if (
ArgType.getArgument().isNull()
3224 ||
ArgType.getArgument().getKind() != clang::TemplateArgument::Type) {
3226 "Template parameter substitution failed for %s around %s\n",
3246 TST->getCanonicalTypeInternal());
3275 llvm::StringRef title;
3278 if (clang::AnnotateAttr *A =
m.getAttr<clang::AnnotateAttr>())
3279 title = A->getAnnotation();
3293 if (title.size() == 0 || (title[0] !=
'['))
return llvm::StringRef();
3295 if (
rightbracket == llvm::StringRef::npos)
return llvm::StringRef();
3314 char *current =
const_cast<char*
>(
working.c_str());
3320 for(i=0;i<
strlen(current);i++) {
3328 return llvm::StringRef();
3333 const clang::CXXRecordDecl *
parent_clxx = llvm::dyn_cast<clang::CXXRecordDecl>(
m.getDeclContext());
3334 const clang::FieldDecl *
index1 =
nullptr;
3347 if (
field_iter->getNameAsString() ==
m.getNameAsString() ) {
3355 return llvm::StringRef();
3367 return llvm::StringRef();
3392 return llvm::StringRef();
3394 if ( found && (
index1->getAccess() == clang::AS_private) ) {
3399 return llvm::StringRef();
3408 return llvm::StringRef();
3429 while((
c =
in[i++])) {
3430 const char *
repl =
nullptr;
3432 case '+':
repl =
"pL";
break;
3433 case '-':
repl =
"mI";
break;
3434 case '*':
repl =
"mU";
break;
3435 case '/':
repl =
"dI";
break;
3436 case '&':
repl =
"aN";
break;
3437 case '%':
repl =
"pE";
break;
3438 case '|':
repl =
"oR";
break;
3439 case '^':
repl =
"hA";
break;
3440 case '>':
repl =
"gR";
break;
3441 case '<':
repl =
"lE";
break;
3442 case '=':
repl =
"eQ";
break;
3443 case '~':
repl =
"wA";
break;
3444 case '.':
repl =
"dO";
break;
3445 case '(':
repl =
"oP";
break;
3446 case ')':
repl =
"cP";
break;
3447 case '[':
repl =
"oB";
break;
3448 case ']':
repl =
"cB";
break;
3449 case '{':
repl =
"lB";
break;
3450 case '}':
repl =
"rB";
break;
3451 case ';':
repl =
"sC";
break;
3452 case '#':
repl =
"hS";
break;
3453 case '?':
repl =
"qM";
break;
3454 case '`':
repl =
"bT";
break;
3455 case '!':
repl =
"nO";
break;
3456 case ',':
repl =
"cO";
break;
3457 case '$':
repl =
"dA";
break;
3458 case ' ':
repl =
"sP";
break;
3459 case ':':
repl =
"cL";
break;
3460 case '"':
repl =
"dQ";
break;
3461 case '@':
repl =
"aT";
break;
3462 case '\'':
repl =
"sQ";
break;
3463 case '\\':
repl =
"fI";
break;
3472 if (out.empty() ||
isdigit(out[0]))
3473 out.insert(out.begin(),
'_');
3476static clang::SourceLocation
3490 const cling::Interpreter&
interp)
3520 using namespace clang;
3545 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>>(),
3560 assert(
decl.isFirstDecl() &&
"Couldn't trace back include from a decl"
3561 " that is not from an AST file");
3586 clang::OptionalFileEntryRef
FELong;
3588 for (llvm::sys::path::const_iterator
3601 &&
"Mismatched partitioning of file name!");
3605 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>>(),
3617 for (llvm::sys::path::reverse_iterator
3625 &&
"Mismatched partitioning of file name!");
3631 ArrayRef<std::pair<OptionalFileEntryRef, DirectoryEntryRef>>(),
3634 nullptr,
nullptr ) ==
FELong) {
3645 const clang::QualType &
qtype,
3657 const clang::QualType &
qtype,
3663 cling::Interpreter::PushTransactionRAII
RAII(
const_cast<cling::Interpreter*
>(&
interpreter));
3675 clang::ClassTemplateDecl*&
ctd,
3676 clang::ClassTemplateSpecializationDecl*&
ctsd)
3678 using namespace clang;
3686 if (
theType->isPointerType()) {
3691 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(
rType->getDecl());
3693 ctd =
ctsd->getSpecializedTemplate();
3703 ctsd = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(
qt->getAsCXXRecordDecl());
3705 ctd =
ctsd->getSpecializedTemplate();
3720 using namespace clang;
3736 using namespace clang;
3755 const clang::NamedDecl&
tPar,
3756 const cling::Interpreter&
interp,
3760 using namespace clang;
3765 if (!
ttpdPtr->hasDefaultArgument())
return false;
3787 const clang::ElaboratedType* etype
3788 = llvm::dyn_cast<clang::ElaboratedType>(
tParQualType.getTypePtr());
3790 tParQualType = clang::QualType(etype->getNamedType().getTypePtr(),0);
3791 etype = llvm::dyn_cast<clang::ElaboratedType>(
tParQualType.getTypePtr());
3795 llvm::dyn_cast<TemplateSpecializationType>(
tParQualType.getTypePtr());
3801 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(
tArgQualType->getAsCXXRecordDecl());
3819 clang::Sema& S =
interp.getCI()->getSema();
3820 cling::Interpreter::PushTransactionRAII
clingRAII(
const_cast<cling::Interpreter*
>(&
interp));
3821 llvm::SmallVector<clang::TemplateArgument, 4>
canonArgs;
3834 newArg.getKind() != clang::TemplateArgument::Type) {
3836 "Template parameter substitution failed!");
3840 = llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(
newArg.getAsType()->getAsCXXRecordDecl());
3856 const clang::NamedDecl&
tPar)
3858 using namespace clang;
3863 if (!
nttpd.hasDefaultArgument())
3868 if (Expr*
defArgExpr =
nttpd.getDefaultArgument().getArgument().getAsExpr()) {
3874 const int value =
tArg.getAsIntegral().getLimitedValue();
3887 using namespace clang;
3888 if (!
nDecl)
return false;
3890 return ttpd->hasDefaultArgument();
3892 return nttpd->hasDefaultArgument();
3899 const cling::Interpreter&
interp,
3904 const clang::TemplateArgument &
tArg,
3905 const cling::Interpreter&
interp,
3907 const clang::ASTContext&
astCtxt)
3910 using namespace clang;
3917 if (
tArg.getKind() == clang::TemplateArgument::Type) {
3926 }
else if (
normTArg.getKind() == clang::TemplateArgument::Pack) {
3927 assert(
tArg.getKind() == clang::TemplateArgument::Pack );
3955 const cling::Interpreter&
interp,
3959 using namespace clang;
3968 const int nArgsToKeep =
normCtxt.GetNargsToKeep(
ctd);
3978 if (llvm::isa<clang::PointerType>(
normalizedType.getTypePtr())) {
3991 if (llvm::isa<clang::ReferenceType>(
normalizedType.getTypePtr())) {
4010 clang::NestedNameSpecifier* prefix =
nullptr;
4012 const clang::ElaboratedType* etype
4013 = llvm::dyn_cast<clang::ElaboratedType>(
normalizedType.getTypePtr());
4019 normalizedType = clang::QualType(etype->getNamedType().getTypePtr(),0);
4027 clang::TemplateParameterList*
tpl =
rd->getTemplateParameters();
4028 if (
tpl->getMinRequiredArguments () <
tpl->size()) {
4035 Error(
"KeepNParams",
"Not found template default arguments\n");
4052 llvm::dyn_cast<TemplateSpecializationType>(
normalizedType.getTypePtr());
4058 const clang::ClassTemplateSpecializationDecl*
TSTdecl
4059 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(
normalizedType.getTypePtr()->getAsCXXRecordDecl());
4067 llvm::SmallVector<TemplateArgument, 4>
argsToKeep;
4080 Error(
"KeepNParams",
"The parameter number %s is null.\n",
formal);
4102 if (
tParPtr->isTemplateParameterPack() ) {
4134 if (
argKind == clang::TemplateArgument::Type){
4137 }
else if (
argKind == clang::TemplateArgument::Integral){
4189 cling::Interpreter::PushTransactionRAII
RAII(
const_cast<cling::Interpreter*
>(&
interpreter));
4212 if (
type.isNull()) {
4220 clang::PrintingPolicy
policy(
ctxt.getPrintingPolicy());
4221 policy.SuppressTagKeyword =
true;
4222 policy.AnonymousTagLocations =
false;
4227 policy.SuppressUnwrittenScope =
true;
4232 cling::Interpreter::PushTransactionRAII
clingRAII(
const_cast<cling::Interpreter*
>(&
interpreter));
4265 clang::ASTContext&
astCtxt =
sema.getASTContext();
4275std::pair<std::string,clang::QualType>
4296 cling::LookupHelper::DiagSetting::NoDiagnostics,
4315 "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());
4343 llvm::errs() << llvm::StringRef(
commentStart, 80) <<
'\n';
4392 if (
const clang::FunctionDecl*
FD = clang::dyn_cast<clang::FunctionDecl>(&
decl)) {
4393 if (
FD->isImplicit()) {
4397 if (
FD->isExplicitlyDefaulted() ||
FD->isDeletedAsWritten()) {
4401 }
else if (
FD->doesThisDeclarationHaveABody()) {
4406 &&
"Expected macro or end of body at '}'");
4418 }
else if (
const clang::EnumConstantDecl*
ECD
4419 = clang::dyn_cast<clang::EnumConstantDecl>(&
decl)) {
4421 if (
ECD->getNextDeclInContext())
4498 if (!
decl)
return false;
4505 static const std::vector<std::string>
signatures =
4506 {
"ClassDef",
"ClassDefOverride",
"ClassDefNV",
"ClassDefInline",
"ClassDefInlineOverride",
"ClassDefInlineNV" };
4523 clang::SourceLocation *
loc,
4526 using namespace clang;
4529 =
interpreter.getLookupHelper().findFunctionProto(&
decl,
"DeclFileLine",
"",
4530 cling::LookupHelper::NoDiagnostics);
4536 if (comment.size()) {
4543 return llvm::StringRef();
4555 if (
rawtype->isElaboratedTypeSpecifier() ) {
4559 rawtype =
type.getTypePtr()->getBaseElementTypeUnsafe ();
4568 if (
rawtype->isElaboratedTypeSpecifier() ) {
4588 if (
ctxt.isNamespace() ||
ctxt.isTranslationUnit())
4590 else if(
const auto parentdecl = llvm::dyn_cast<clang::CXXRecordDecl>(&
ctxt))
4603 const clang::DeclContext *
ctxt =
decl.getDeclContext();
4604 switch (
decl.getAccess()) {
4605 case clang::AS_public:
4607 case clang::AS_protected:
4609 case clang::AS_private:
4611 case clang::AS_none:
4615 assert(
false &&
"Unexpected value for the access property value in Clang");
4625 return cling::utils::Analyze::IsStdClass(cl);
4635 if (cling::utils::Analyze::IsStdClass(cl)) {
4636 static const char *names[] =
4637 {
"shared_ptr",
"__shared_ptr",
4638 "vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset"};
4639 llvm::StringRef
clname(cl.getName());
4640 for(
auto &&
name : names) {
4678 const clang::CXXRecordDecl *
thisDecl =
4679 llvm::dyn_cast_or_null<clang::CXXRecordDecl>(
lh.findScope(
typ, cling::LookupHelper::WithDiagnostics));
4683 Error(
"IsOfType",
"Record decl of type %s not found in the AST.",
typ.c_str());
4713 if (!IsStdClass(cl)) {
4714 auto *
nsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext());
4715 if (cl.getName() !=
"RVec" ||
nsDecl ==
nullptr ||
nsDecl->getName() !=
"VecOps")
4718 auto *
parentNsDecl = llvm::dyn_cast<clang::NamespaceDecl>(cl.getDeclContext()->getParent());
4723 return STLKind(cl.getName());
4727 using namespace clang;
4728 struct SearchTypedef:
public TypeVisitor<SearchTypedef, bool> {
4733 return Visit(
AT->getElementType().getTypePtr());
4736 return Visit(
DT->getUnderlyingType().getTypePtr());
4739 return Visit(
PT->getPointeeType().getTypePtr());
4742 return Visit(
RT->getPointeeType().getTypePtr());
4745 return Visit(
STST->getReplacementType().getTypePtr());
4749 if (
TA.getKind() == TemplateArgument::Type && Visit(
TA.getAsType().getTypePtr()))
4758 return TOT->getUnmodifiedType().getTypePtr();
4763 if (
NNS->getKind() == NestedNameSpecifier::TypeSpec) {
4764 if (Visit(
NNS->getAsType()))
4769 return Visit(
ET->getNamedType().getTypePtr());
4790 using namespace llvm;
4791 using namespace clang;
4792 const clang::ASTContext &
Ctxt =
instance->getAsCXXRecordDecl()->getASTContext();
4795 const clang::ElaboratedType* etype
4796 = llvm::dyn_cast<clang::ElaboratedType>(
input.getTypePtr());
4801 assert(
instance->getAsCXXRecordDecl() !=
nullptr &&
"ReSubstTemplateArg only makes sense with a type representing a class.");
4821 if (
nQT ==
QT->getPointeeType())
return QT;
4837 if (
nQT ==
QT->getPointeeType())
return QT;
4858 if (
newQT ==
arr->getElementType())
return QT;
4862 arr->getSizeModifier(),
4863 arr->getIndexTypeCVRQualifiers());
4871 arr->getSizeModifier(),
4872 arr->getIndexTypeCVRQualifiers(),
4873 arr->getBracketsRange());
4878 if (
newQT ==
arr->getElementType())
return QT;
4880 arr->getSizeModifier(),
4881 arr->getIndexTypeCVRQualifiers());
4886 if (
newQT ==
arr->getElementType())
return QT;
4889 arr->getSizeModifier(),
4890 arr->getIndexTypeCVRQualifiers(),
4891 arr->getBracketsRange());
4900 etype = llvm::dyn_cast<clang::ElaboratedType>(
instance);
4902 instance = etype->getNamedType().getTypePtr();
4906 const clang::TemplateSpecializationType*
TST
4907 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
instance);
4911 const clang::ClassTemplateSpecializationDecl*
TSTdecl
4912 = llvm::dyn_cast_or_null<const clang::ClassTemplateSpecializationDecl>(
instance->getAsCXXRecordDecl());
4916 const clang::SubstTemplateTypeParmType *
substType
4917 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(
input.getTypePtr());
4921 const clang::ClassTemplateDecl *
replacedCtxt =
nullptr;
4925 unsigned int index =
substType->getReplacedParameter()->getIndex();
4928 if (
decl->getKind() == clang::Decl::ClassTemplatePartialSpecialization) {
4929 const clang::ClassTemplatePartialSpecializationDecl *
spec = llvm::dyn_cast<clang::ClassTemplatePartialSpecializationDecl>(
decl);
4931 unsigned int depth =
substType->getReplacedParameter()->getDepth();
4947 const clang::SubstTemplateTypeParmType *
argType
4948 = llvm::dyn_cast<clang::SubstTemplateTypeParmType>(
argQualType);
4973 llvm::raw_string_ostream ostream(
astDump);
4976 ROOT::TMetaUtils::Warning(
"ReSubstTemplateArg",
"Unexpected type of declaration context for template parameter: %s.\n\tThe responsible class is:\n\t%s\n",
4983 const auto &
TAs =
TST->template_arguments();
5000 const clang::TemplateSpecializationType*
inputTST
5001 = llvm::dyn_cast<const clang::TemplateSpecializationType>(
input.getTypePtr());
5006 llvm::SmallVector<clang::TemplateArgument, 4>
desArgs;
5007 for (
const clang::TemplateArgument &
TA :
inputTST->template_arguments()) {
5008 if (
TA.getKind() != clang::TemplateArgument::Type) {
5013 clang::QualType
SubTy =
TA.getAsType();
5015 if (llvm::isa<clang::ElaboratedType>(
SubTy)
5016 || llvm::isa<clang::SubstTemplateTypeParmType>(
SubTy)
5017 || llvm::isa<clang::TemplateSpecializationType>(
SubTy)) {
5032 inputTST->getCanonicalTypeInternal());
5073 static const char *
stls[] =
5074 {
"any",
"vector",
"list",
"deque",
"map",
"multimap",
"set",
"multiset",
"bitset",
5075 "forward_list",
"unordered_set",
"unordered_multiset",
"unordered_map",
"unordered_multimap",
"RVec",
nullptr};
5089 for (
int k = 1;
stls[k]; k++) {
5103 TND =
TND->getMostRecentDecl();
5104 while (
TND && !(
TND->hasAttrs()))
5105 TND =
TND->getPreviousDecl();
5117 TD =
TD->getMostRecentDecl();
5118 while (
TD && !(
TD->hasAttrs() &&
TD->isThisDeclarationADefinition()))
5119 TD =
TD->getPreviousDecl();
5175 std::list<std::pair<std::string,unsigned int> >&
enclosingSc)
5203 std::string::size_type
beginVar = 0;
5204 std::string::size_type
endVar = 0;
5208 std::string::size_type
endVarName = std::string::npos;
5250 const char*
envInclPath = std::getenv(
"ROOT_INCLUDE_PATH");
5285 str.replace(
start_pos, from.length(), to);
5352 return llvm::sys::path::extension(
filename) ==
".h" ||
5353 llvm::sys::path::extension(
filename) ==
".hh" ||
5354 llvm::sys::path::extension(
filename) ==
".hpp" ||
5355 llvm::sys::path::extension(
filename) ==
".H" ||
5356 llvm::sys::path::extension(
filename) ==
".h++" ||
5357 llvm::sys::path::extension(
filename) ==
"hxx" ||
5358 llvm::sys::path::extension(
filename) ==
"Hxx" ||
5359 llvm::sys::path::extension(
filename) ==
"HXX";
5365 cling::Interpreter::IgnoreFilesFunc_t
ignoreFiles,
5366 const cling::Interpreter &
interp,
5374 clang::Decl *
ncDecl =
const_cast<clang::Decl *
>(
decl);
5419 static const std::string
scopeType [] = {
"namespace ",
"inline namespace ",
"class "};
5461 std::string typeName;
5464 if (llvm::isa<clang::TemplateTypeParmDecl>(
nDecl)){
5465 typeName =
"typename ";
5466 if (
nDecl->isParameterPack())
5468 typeName += (*prmIt)->getNameAsString();
5471 else if (
auto nttpd = llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(
nDecl)){
5475 if (
theType.getAsString().find(
"enum") != std::string::npos){
5477 llvm::raw_string_ostream ostream(
astDump);
5478 nttpd->dump(ostream);
5489 else if (
auto ttpd = llvm::dyn_cast<clang::TemplateTemplateParmDecl>(
nDecl)){
5493 llvm::raw_string_ostream ostream(
astDump);
5494 ttpd->dump(ostream);
5519 "Cannot extract template parameter list for %s",
5527 "Problems with arguments for forward declaration of class %s\n",
5537 if (llvm::isa<clang::TemplateTemplateParmDecl>(&
templDecl)) {
5559 if (clang::TemplateArgument::Type != arg.getKind())
return 0;
5574 if (llvm::isa<clang::BuiltinType>(
argTypePtr)){
5607 if (
specDef->getTemplateSpecializationKind() != clang::TSK_ExplicitSpecialization)
5611 std::cout <<
" Forward declaring template spec " <<
normalizedName <<
":\n";
5616 std::cout <<
" o Template argument ";
5618 std::cout <<
"successfully treated. Arg fwd decl: " <<
argFwdDecl << std::endl;
5620 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5661 std::cout <<
"Class " <<
recordDecl.getNameAsString()
5662 <<
" is a template specialisation. Treating its arguments.\n";
5666 std::cout <<
" o Template argument ";
5668 std::cout <<
"successfully treated. Arg fwd decl: " <<
argFwdDecl << std::endl;
5670 std::cout <<
"could not be treated. Abort fwd declaration generation.\n";
5718 std::string buffer =
tdnDecl.getNameAsString();
5721 if (
const clang::TagType* TT
5723 if (clang::NamedDecl*
ND = TT->getDecl()) {
5724 if (!
ND->getIdentifier()) {
5768 std::cout <<
"Typedef " <<
tdnDecl.getNameAsString() <<
" hides a class: "
5795 const clang::PrintingPolicy&
ppolicy)
5798 auto&
ctxt = par.getASTContext();
5819 if (
result.isNegative()){
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
short Version_t
Class version identifier (short)
static void indent(ostringstream &buf, int indent_level)
static bool RecurseKeepNParams(clang::TemplateArgument &normTArg, const clang::TemplateArgument &tArg, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt, const clang::ASTContext &astCtxt)
static clang::SourceLocation getFinalSpellingLoc(clang::SourceManager &sourceManager, clang::SourceLocation sourceLoc)
const clang::DeclContext * GetEnclosingSpace(const clang::RecordDecl &cl)
bool IsTemplate(const clang::Decl &cl)
static void KeepNParams(clang::QualType &normalizedType, const clang::QualType &vanillaType, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
This function allows to manipulate the number of arguments in the type of a template specialisation.
static void CreateNameTypeMap(const clang::CXXRecordDecl &cl, ROOT::MembersTypeMap_t &nameType)
Create the data member name-type map for given class.
const clang::CXXMethodDecl * GetMethodWithProto(const clang::Decl *cinfo, const char *method, const char *proto, const cling::Interpreter &interp, bool diagnose)
int dumpDeclForAssert(const clang::Decl &D, const char *commentStart)
static void replaceEnvVars(const char *varname, std::string &txt)
Reimplementation of TSystem::ExpandPathName() that cannot be used from TMetaUtils.
static bool areEqualValues(const clang::TemplateArgument &tArg, const clang::NamedDecl &tPar)
std::cout << "Are equal values?\n";
static bool isTypeWithDefault(const clang::NamedDecl *nDecl)
Check if this NamedDecl is a template parameter with a default argument.
static int TreatSingleTemplateArg(const clang::TemplateArgument &arg, std::string &argFwdDecl, const cling::Interpreter &interpreter, bool acceptStl=false)
static bool areEqualTypes(const clang::TemplateArgument &tArg, llvm::SmallVectorImpl< clang::TemplateArgument > &preceedingTArgs, const clang::NamedDecl &tPar, const cling::Interpreter &interp, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt)
static bool hasSomeTypedefSomewhere(const clang::Type *T)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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.
winID h TVirtualViewer3D TVirtualGLPainter p
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 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 target
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_iterator begin() const
const_iterator end() const
A RAII helper to remove and readd enclosing _Atomic() It expects no spaces at the beginning or end of...
const std::string & GetPathSeparator()
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)
void GetNormalizedName(std::string &norm_name, std::string_view name)
Return the normalized name.
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 .