34 #include "cling/Interpreter/Interpreter.h"
35 #include "cling/Interpreter/LookupHelper.h"
36 #include "cling/Utils/AST.h"
38 #include "clang/AST/ASTContext.h"
39 #include "clang/AST/Decl.h"
40 #include "clang/AST/DeclCXX.h"
41 #include "clang/AST/DeclTemplate.h"
42 #include "clang/AST/GlobalDecl.h"
43 #include "clang/AST/PrettyPrinter.h"
44 #include "clang/AST/RecordLayout.h"
45 #include "clang/AST/Type.h"
46 #include "clang/Basic/Specifiers.h"
47 #include "clang/Frontend/CompilerInstance.h"
48 #include "clang/Sema/Sema.h"
50 #include "llvm/ExecutionEngine/GenericValue.h"
51 #include "llvm/Support/Casting.h"
52 #include "llvm/Support/raw_ostream.h"
57 using namespace clang;
63 if (
const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(decl)) {
64 PrintingPolicy Policy(decl->getASTContext().getPrintingPolicy());
65 llvm::raw_string_ostream stream(buf);
66 ND->getNameForDiagnostic(stream, Policy,
true);
72 : fInterp(interp), fFirstTime(true), fDescend(
false), fIterAll(all),
73 fDecl(0),
fType(0), fOffsetCache(0)
75 TranslationUnitDecl *TU =
76 interp->getCI()->getASTContext().getTranslationUnitDecl();
78 cling::Interpreter::PushTransactionRAII RAII(interp);
80 fIter = TU->decls_begin();
82 fIter = TU->noload_decls_begin();
103 : fInterp(interp), fFirstTime(true), fDescend(
false), fIterAll(
kTRUE), fDecl(0),
104 fType(0), fTitle(
""), fOffsetCache(0)
106 const cling::LookupHelper& lh =
fInterp->getLookupHelper();
108 const Decl *decl = lh.findScope(name,
109 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
110 : cling::LookupHelper::NoDiagnostics,
115 decl = lh.findScope(buf,
116 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
117 : cling::LookupHelper::NoDiagnostics,
122 const TagType *tagtype =type->getAs<TagType>();
124 decl = tagtype->getDecl();
129 if (decl && decl->isInvalidDecl()) {
130 Error(
"TClingClassInfo",
"Found an invalid decl for %s.",name);
138 : fInterp(interp), fFirstTime(true), fDescend(
false), fIterAll(
kTRUE),
139 fDecl(0),
fType(0), fTitle(
""), fOffsetCache(0)
150 fOffsetCache[decl] = std::make_pair(offset, executableFunc);
159 const RecordDecl *RD = llvm::dyn_cast<RecordDecl>(
fDecl);
170 const CXXRecordDecl *CRD =
171 llvm::dyn_cast<CXXRecordDecl>(
fDecl);
173 if (CRD->isAbstract()) {
176 if (CRD->hasUserDeclaredConstructor()) {
180 !CRD->hasUserDeclaredConstructor() &&
181 !CRD->hasTrivialDefaultConstructor()
186 CRD->hasUserProvidedDefaultConstructor() ||
187 !CRD->hasTrivialDefaultConstructor()
191 if (CRD->hasUserDeclaredDestructor()) {
194 else if (!CRD->hasTrivialDestructor()) {
197 if (CRD->hasUserDeclaredCopyAssignment()) {
200 if (CRD->isPolymorphic()) {
211 Error(
"TClingClassInfo::Delete()",
"Called while invalid!");
215 Error(
"TClingClassInfo::Delete()",
"Class is not loaded: %s",
236 Error(
"DeleteArray",
"Placement delete of an array is unsupported!\n");
263 const TypedefType *TT = llvm::dyn_cast<TypedefType>(
fType);
265 llvm::StringRef tname(TT->getDecl()->getName());
266 if (tname.equals(fname)) {
267 const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(
fDecl);
268 if (ndecl && !ndecl->getName().equals(fname)) {
275 const cling::LookupHelper &lh =
fInterp->getLookupHelper();
276 const FunctionTemplateDecl *fd
277 = lh.findFunctionTemplate(
fDecl, fname,
278 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
279 : cling::LookupHelper::NoDiagnostics,
false);
280 if (fd)
return fd->getCanonicalDecl();
289 const cling::LookupHelper &lh =
fInterp->getLookupHelper();
291 = lh.findDataMember(
fDecl, name,
292 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
293 : cling::LookupHelper::NoDiagnostics);
294 if (vd)
return llvm::dyn_cast<ValueDecl>(vd->getCanonicalDecl());
310 const TypedefType *TT = llvm::dyn_cast<TypedefType>(
fType);
312 llvm::StringRef tname(TT->getDecl()->getName());
313 if (tname.equals(fname)) {
314 const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(
fDecl);
315 if (ndecl && !ndecl->getName().equals(fname)) {
317 return GetMethod(ndecl->getName().str().c_str());
322 const cling::LookupHelper &lh =
fInterp->getLookupHelper();
323 const FunctionDecl *fd
324 = lh.findAnyFunction(
fDecl, fname,
325 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
326 : cling::LookupHelper::NoDiagnostics,
342 return GetMethod(fname,proto,
false,poffset,mode,imode);
346 const char *proto,
bool objectIsConst,
361 const TypedefType *TT = llvm::dyn_cast<TypedefType>(
fType);
363 llvm::StringRef tname(TT->getDecl()->getName());
364 if (tname.equals(fname)) {
365 const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(
fDecl);
366 if (ndecl && !ndecl->getName().equals(fname)) {
368 return GetMethod(ndecl->getName().str().c_str(),proto,
369 objectIsConst,poffset,
376 const cling::LookupHelper& lh =
fInterp->getLookupHelper();
377 const FunctionDecl *fd;
379 fd = lh.findFunctionProto(
fDecl, fname, proto,
380 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
381 : cling::LookupHelper::NoDiagnostics,
384 fd = lh.matchFunctionProto(
fDecl, fname, proto,
385 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
386 : cling::LookupHelper::NoDiagnostics,
389 Error(
"TClingClassInfo::GetMethod",
390 "The MatchMode %d is not supported.", mode);
408 const clang::DeclContext* ourDC = llvm::dyn_cast<clang::DeclContext>(
fDecl);
409 if (!fd->getDeclContext()->Equals(ourDC)
410 && !(fd->getDeclContext()->isTransparentContext()
411 && fd->getDeclContext()->getParent()->Equals(ourDC)))
415 if (poffset) *poffset = 0;
419 if (
const CXXMethodDecl *md =
420 llvm::dyn_cast<CXXMethodDecl>(fd)) {
432 const llvm::SmallVectorImpl<clang::QualType> &proto,
436 return GetMethod(fname,proto,
false,poffset,mode,imode);
440 const llvm::SmallVectorImpl<clang::QualType> &proto,
bool objectIsConst,
455 const TypedefType *TT = llvm::dyn_cast<TypedefType>(
fType);
457 llvm::StringRef tname(TT->getDecl()->getName());
458 if (tname.equals(fname)) {
459 const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(
fDecl);
460 if (ndecl && !ndecl->getName().equals(fname)) {
462 return GetMethod(ndecl->getName().str().c_str(),proto,objectIsConst,poffset,
469 const cling::LookupHelper& lh =
fInterp->getLookupHelper();
470 const FunctionDecl *fd;
472 fd = lh.findFunctionProto(
fDecl, fname, proto,
473 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
474 : cling::LookupHelper::NoDiagnostics,
477 fd = lh.matchFunctionProto(
fDecl, fname, proto,
478 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
479 : cling::LookupHelper::NoDiagnostics,
482 Error(
"TClingClassInfo::GetMethod",
483 "The MatchMode %d is not supported.", mode);
494 if (
const CXXMethodDecl *md =
495 llvm::dyn_cast<CXXMethodDecl>(fd)) {
513 const char *arglist,
bool objectIsConst,
521 const TypedefType *TT = llvm::dyn_cast<TypedefType>(
fType);
523 llvm::StringRef tname(TT->getDecl()->getName());
524 if (tname.equals(fname)) {
525 const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(
fDecl);
526 if (ndecl && !ndecl->getName().equals(fname)) {
528 return GetMethod(ndecl->getName().str().c_str(),arglist,
529 objectIsConst,poffset
543 if (!strcmp(arglist,
")")) {
547 const cling::LookupHelper &lh =
fInterp->getLookupHelper();
548 const FunctionDecl *fd
549 = lh.findFunctionArgs(
fDecl, fname, arglist,
550 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
551 : cling::LookupHelper::NoDiagnostics,
560 if (
const CXXMethodDecl *md =
561 llvm::dyn_cast<CXXMethodDecl>(fd)) {
586 clang_val =
static_cast<int>(num_params);
597 const CXXRecordDecl* definer = md->getParent();
598 const CXXRecordDecl* accessor =
599 llvm::cast<CXXRecordDecl>(
fDecl);
600 if (definer != accessor) {
607 if (bci->
GetDecl() == definer) {
626 std::pair<ptrdiff_t, OffsetPtrFunc_t> offsetCache = (*iter).second;
629 return (*executableFunc)(address, isDerivedObject);
632 Error(
"TClingBaseClassInfo::Offset",
"The address of the object for virtual base offset calculation is not valid.");
637 return offsetCache.first;
643 return binfo.
Offset(address, isDerivedObject);
646 static bool HasBody(
const clang::FunctionDecl &decl,
const cling::Interpreter &interp)
648 if (decl.hasBody())
return true;
651 if (
const CXXConstructorDecl* Ctor = dyn_cast<CXXConstructorDecl>(&decl))
652 GD = GlobalDecl(Ctor, Ctor_Complete);
653 else if (
const CXXDestructorDecl* Dtor = dyn_cast<CXXDestructorDecl>(&decl))
654 GD = GlobalDecl(Dtor, Dtor_Deleting);
656 GD = GlobalDecl(&decl);
657 std::string mangledName;
658 cling::utils::Analyze::maybeMangleDeclName(GD, mangledName);
660 void *GV = interp.getAddressOfGlobal(mangledName.c_str());
679 const CXXRecordDecl* CRD = llvm::dyn_cast<CXXRecordDecl>(
fDecl);
684 if (CRD->hasTrivialDefaultConstructor()) {
690 cling::Interpreter::PushTransactionRAII pushedT(
fInterp);
691 for (CXXRecordDecl::ctor_iterator
I = CRD->ctor_begin(),
692 E = CRD->ctor_end();
I !=
E; ++
I) {
693 if (
I->getMinRequiredArguments() == 0) {
697 if (
I->isTemplateInstantiation()) {
698 const clang::FunctionDecl* FD =
699 I->getInstantiatedFromMemberFunction();
713 return fInterp->getLookupHelper()
714 .hasFunction(
fDecl, name,
715 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
716 : cling::LookupHelper::NoDiagnostics);
725 fIter = DeclContext::decl_iterator();
729 const cling::LookupHelper& lh =
fInterp->getLookupHelper();
730 fDecl = lh.findScope(name,
gDebug > 5 ? cling::LookupHelper::WithDiagnostics
731 : cling::LookupHelper::NoDiagnostics,
736 fDecl = lh.findScope(buf,
gDebug > 5 ? cling::LookupHelper::WithDiagnostics
737 : cling::LookupHelper::NoDiagnostics,
742 const TagType *tagtype =
fType->getAs<TagType>();
744 fDecl = tagtype->getDecl();
753 fIter = DeclContext::decl_iterator();
761 Fatal(
"TClingClassInfo::Init(tagnum)",
"Should no longer be called");
771 const TagType *tagtype =
fType->getAs<TagType>();
773 fDecl = tagtype->getDecl();
779 QualType qType(
fType,0);
780 static PrintingPolicy printPol(
fInterp->getCI()->getLangOpts());
781 printPol.SuppressScope =
false;
782 Error(
"TClingClassInfo::Init(const Type&)",
783 "The given type %s does not point to a Decl",
784 qType.getAsString(printPol).c_str());
800 const CXXRecordDecl *CRD =
801 llvm::dyn_cast<CXXRecordDecl>(
fDecl);
807 const CXXRecordDecl *baseCRD =
808 llvm::dyn_cast<CXXRecordDecl>(base.
GetDecl());
809 return CRD->isDerivedFrom(baseCRD);
837 const CXXRecordDecl *CRD = llvm::dyn_cast<CXXRecordDecl>(
fDecl);
839 if (!CRD->hasDefinition()) {
843 const TagDecl *TD = llvm::dyn_cast<TagDecl>(
fDecl);
844 if (TD && TD->getDefinition() == 0) {
882 if (
const NamedDecl* ND =
883 llvm::dyn_cast<NamedDecl>(
fDecl)) {
884 PrintingPolicy Policy(
fDecl->getASTContext().
885 getPrintingPolicy());
886 llvm::raw_string_ostream stream(buf);
887 ND->getNameForDiagnostic(stream, Policy,
false);
889 Error(
"TClingClassInfo::InternalNext",
890 "Next called but iteration not prepared for %s!", buf.c_str());
894 cling::Interpreter::PushTransactionRAII pushedT(
fInterp);
916 DeclContext *DC = llvm::cast<DeclContext>(*fIter);
918 fIter = DC->decls_begin();
920 fIter = DC->noload_decls_begin();
940 Decl::Kind DK =
fIter->getKind();
942 (DK == Decl::CXXRecord) ||
943 (DK == Decl::ClassTemplateSpecialization)) {
944 const TagDecl *TD = llvm::dyn_cast<TagDecl>(*fIter);
945 if (TD && !TD->isCompleteDefinition()) {
951 if (!fIter->isCanonicalDecl()) {
959 DeclContext *DC = llvm::cast<DeclContext>(*fIter);
960 if ((
fIterAll && *DC->decls_begin())
961 || (!
fIterAll && *DC->noload_decls_begin())) {
971 if (
fDecl->isInvalidDecl()) {
972 Warning(
"TClingClassInfo::Next()",
"Reached an invalid decl.");
974 if (
const RecordDecl *RD =
975 llvm::dyn_cast<RecordDecl>(
fDecl)) {
976 fType = RD->getASTContext().getRecordType(RD).getTypePtr();
994 Error(
"TClingClassInfo::New()",
"Called while invalid!");
998 Error(
"TClingClassInfo::New()",
"Class is not loaded: %s",
1004 const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(
fDecl);
1006 Error(
"TClingClassInfo::New()",
"This is a namespace!: %s",
1021 Error(
"TClingClassInfo::New()",
"Call of default constructor "
1022 "failed to return an object for class: %s",
1035 Error(
"TClingClassInfo::New(n)",
"Called while invalid!");
1039 Error(
"TClingClassInfo::New(n)",
"Class is not loaded: %s",
1047 const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(
fDecl);
1049 Error(
"TClingClassInfo::New(n)",
"This is a namespace!: %s",
1066 Error(
"TClingClassInfo::New(n)",
"Call of default constructor "
1067 "failed to return an array of class: %s",
1081 Error(
"TClingClassInfo::New(n, arena)",
"Called while invalid!");
1085 Error(
"TClingClassInfo::New(n, arena)",
"Class is not loaded: %s",
1092 const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(
fDecl);
1094 Error(
"TClingClassInfo::New(n, arena)",
"This is a namespace!: %s",
1120 Error(
"TClingClassInfo::New(arena)",
"Called while invalid!");
1124 Error(
"TClingClassInfo::New(arena)",
"Class is not loaded: %s",
1131 const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(
fDecl);
1133 Error(
"TClingClassInfo::New(arena)",
"This is a namespace!: %s",
1162 const clang::DeclContext *ctxt =
fDecl->getDeclContext();
1163 clang::NamespaceDecl *std_ns =
fInterp->getSema().getStdNamespace();
1164 while (! ctxt->isTranslationUnit()) {
1165 if (ctxt->Equals(std_ns)) {
1169 ctxt = ctxt->getParent();
1171 Decl::Kind DK =
fDecl->getKind();
1177 const TagDecl *TD = llvm::dyn_cast<TagDecl>(
fDecl);
1186 const CXXRecordDecl *CRD =
1187 llvm::dyn_cast<CXXRecordDecl>(
fDecl);
1188 if (CRD->isClass()) {
1191 else if (CRD->isStruct()) {
1194 else if (CRD->isUnion()) {
1197 if (CRD->hasDefinition() && CRD->isAbstract()) {
1224 Decl::Kind DK =
fDecl->getKind();
1233 const RecordDecl *RD = llvm::dyn_cast<RecordDecl>(
fDecl);
1238 if (!RD->getDefinition()) {
1243 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
1244 const ASTRecordLayout &
Layout = Context.getASTRecordLayout(RD);
1245 int64_t size = Layout.getSize().getQuantity();
1246 int clang_size =
static_cast<int>(size);
1255 return reinterpret_cast<long>(
fDecl);
1279 if (
const NamedDecl* ND =
1280 llvm::dyn_cast<NamedDecl>(
fDecl)) {
1281 PrintingPolicy Policy(
fDecl->getASTContext().
1282 getPrintingPolicy());
1283 llvm::raw_string_ostream stream(output);
1284 ND->getNameForDiagnostic(stream, Policy,
true);
1296 TTHREAD_TLS_DECL( std::string, buf);
1299 if (
const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(
fDecl)) {
1300 PrintingPolicy Policy(
fDecl->getASTContext().getPrintingPolicy());
1301 llvm::raw_string_ostream stream(buf);
1302 ND->getNameForDiagnostic(stream, Policy,
false);
1320 if (
const TagDecl *TD = llvm::dyn_cast<TagDecl>(
GetDecl())) {
1322 if (AnnotateAttr *
A = TD->getAttr<AnnotateAttr>()) {
1323 std::string
attr =
A->getAnnotation().str();
1339 const CXXRecordDecl *CRD =
1340 llvm::dyn_cast<CXXRecordDecl>(
GetDecl());
1341 if (CRD && !CRD->isFromASTFile()) {
1356 TTHREAD_TLS_DECL( std::string, buf);
1358 if (
const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(
fDecl)) {
1360 buf = ND->getNameAsString();
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
void AddBaseOffsetValue(const clang::Decl *decl, ptrdiff_t offset)
llvm::DenseMap< const clang::Decl *, std::pair< ptrdiff_t, OffsetPtrFunc_t > > fOffsetCache
void Fatal(const char *location, const char *msgfmt,...)
const char * Name() const
RooArgList L(const RooAbsArg &v1)
const clang::Type * fType
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
R__EXTERN TVirtualMutex * gInterpreterMutex
bool HasMethod(const char *name) const
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Small helper to keep current directory context.
Emulation of the CINT MethodInfo class.
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
std::string InsertStd(const char *tname)
bool HasDefaultConstructor() const
TClingMethodInfo GetMethod(const char *fname) const
ClassImp(TIterator) Bool_t TIterator return false
Compare two iterator objects.
Emulation of the CINT CallFunc class.
ptrdiff_t(* OffsetPtrFunc_t)(void *, bool)
const clang::Decl * fDecl
long ClassProperty() const
std::map< std::string, std::string >::const_iterator iter
static bool IsEnum(cling::Interpreter *interp, const char *name)
void Error(const char *location, const char *msgfmt,...)
long GetOffset(const clang::CXXMethodDecl *md) const
std::string fDeclFileName
const char * TmpltName() const
void Init(const char *name)
TClingClassInfo * GetBase() const
void Init(const clang::FunctionDecl *)
Emulation of the CINT BaseClassInfo class.
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
const clang::FunctionDecl * GetMethodDecl() const
void Warning(const char *location, const char *msgfmt,...)
Type
enumeration specifying the integration types.
const clang::Decl * GetDecl() const
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Emulation of the CINT ClassInfo class.
#define R__LOCKGUARD(mutex)
const clang::ValueDecl * GetDataMember(const char *name) const
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * ExecDefaultConstructor(const TClingClassInfo *info, void *address=0, unsigned long nary=0UL)
static bool HasBody(const clang::FunctionDecl &decl, const cling::Interpreter &interp)
RooCmdArg Layout(Double_t xmin, Double_t xmax=0.99, Double_t ymin=0.95)
clang::DeclContext::decl_iterator fIter
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, long *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
void ExecDestructor(const TClingClassInfo *info, void *address=0, unsigned long nary=0UL, bool withFree=true)
static std::string FullyQualifiedName(const Decl *decl)
std::vector< clang::DeclContext::decl_iterator > fIterStack
bool IsBase(const char *name) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, long *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
cling::Interpreter * fInterp
static void output(int code)