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"
67 llvm::raw_string_ostream stream(buf);
68 ND->getNameForDiagnostic(stream, Policy,
true);
75 fIsIter(
true), fOffsetCache(0)
78 interp->getCI()->getASTContext().getTranslationUnitDecl();
87 const cling::LookupHelper&
lh =
fInterp->getLookupHelper();
88 const Type *
type =
nullptr;
90 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
91 : cling::LookupHelper::NoDiagnostics,
97 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
98 : cling::LookupHelper::NoDiagnostics,
103 if (
const auto *
TD =
type->getAsTagDecl()) {
109 if (
decl &&
decl->isInvalidDecl()) {
110 Error(
"TClingClassInfo",
"Found an invalid decl for %s.",
name);
119 fIsIter(
false), fOffsetCache(0)
127 fIsIter(
false), fOffsetCache(0)
151 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
164 llvm::dyn_cast<CXXRecordDecl>(
GetDecl());
168 if (
CRD->isAbstract()) {
171 if (
CRD->hasUserDeclaredConstructor()) {
175 !
CRD->hasUserDeclaredConstructor() &&
176 !
CRD->hasTrivialDefaultConstructor()
181 CRD->hasUserProvidedDefaultConstructor() ||
182 !
CRD->hasTrivialDefaultConstructor()
186 if (
CRD->hasUserDeclaredDestructor()) {
189 else if (!
CRD->hasTrivialDestructor()) {
192 if (
CRD->hasUserDeclaredCopyAssignment()) {
195 if (
CRD->isPolymorphic()) {
198 if (
CRD->isAggregate() ||
CRD->isPOD()) {
210 Error(
"TClingClassInfo::Delete()",
"Called while invalid!");
214 Error(
"TClingClassInfo::Delete()",
"Class is not loaded: %s",
219 cf.ExecDestructor(
this,
arena, 0,
true);
235 Error(
"DeleteArray",
"Placement delete of an array is unsupported!\n");
239 cf.ExecDestructor(
this,
arena, 1,
true);
250 cf.ExecDestructor(
this,
arena, 0,
false);
264 llvm::StringRef
tname(TT->getDecl()->getName());
274 const cling::LookupHelper &
lh =
fInterp->getLookupHelper();
277 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
278 : cling::LookupHelper::NoDiagnostics,
false);
279 if (fd)
return fd->getCanonicalDecl();
288 const cling::LookupHelper &
lh =
fInterp->getLookupHelper();
291 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
292 : cling::LookupHelper::NoDiagnostics);
293 if (
vd)
return llvm::dyn_cast<ValueDecl>(
vd->getCanonicalDecl());
311 llvm::StringRef
tname(TT->getDecl()->getName());
321 const cling::LookupHelper &
lh =
fInterp->getLookupHelper();
324 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
325 : cling::LookupHelper::NoDiagnostics,
362 llvm::StringRef
tname(TT->getDecl()->getName());
375 const cling::LookupHelper&
lh =
fInterp->getLookupHelper();
379 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
380 : cling::LookupHelper::NoDiagnostics,
384 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
385 : cling::LookupHelper::NoDiagnostics,
388 Error(
"TClingClassInfo::GetMethod",
389 "The MatchMode %d is not supported.",
mode);
407 const clang::DeclContext*
ourDC = llvm::dyn_cast<clang::DeclContext>(
GetDecl());
408 if (!fd->getDeclContext()->Equals(
ourDC)
409 && !(fd->getDeclContext()->isTransparentContext()
410 && fd->getDeclContext()->getParent()->Equals(
ourDC)))
419 llvm::dyn_cast<CXXMethodDecl>(fd)) {
431 const llvm::SmallVectorImpl<clang::QualType> &
proto,
456 llvm::StringRef
tname(TT->getDecl()->getName());
468 const cling::LookupHelper&
lh =
fInterp->getLookupHelper();
472 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
473 : cling::LookupHelper::NoDiagnostics,
477 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
478 : cling::LookupHelper::NoDiagnostics,
481 Error(
"TClingClassInfo::GetMethod",
482 "The MatchMode %d is not supported.",
mode);
494 llvm::dyn_cast<CXXMethodDecl>(fd)) {
522 llvm::StringRef
tname(TT->getDecl()->getName());
546 const cling::LookupHelper &
lh =
fInterp->getLookupHelper();
549 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
550 : cling::LookupHelper::NoDiagnostics,
560 llvm::dyn_cast<CXXMethodDecl>(fd)) {
584 unsigned num_params =
mi.GetTargetFunctionDecl()->getNumParams();
598 llvm::cast<CXXRecordDecl>(
GetDecl());
626 std::pair<ptrdiff_t, OffsetPtrFunc_t>
offsetCache = (*iter).second;
632 Error(
"TClingBaseClassInfo::Offset",
"The address of the object for virtual base offset calculation is not valid.");
651 std::vector<std::string> res;
655 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
660 clang::PrintingPolicy
policy(
fDecl->getASTContext().getPrintingPolicy());
661 for (
auto UD :
DC->using_directives()) {
665 llvm::raw_string_ostream stream(
nsName);
667 NS->getNameForDiagnostic(stream,
policy,
true);
691 return EIOCtorCategory::kAbsent;
693 auto CRD = llvm::dyn_cast<CXXRecordDecl>(
GetDecl());
696 return EIOCtorCategory::kAbsent;
699 auto kind = CheckIOConstructor(
CRD,
"TRootIOCtor",
nullptr, *
fInterp);
700 if ((kind == EIOCtorCategory::kIORefType) || (kind == EIOCtorCategory::kIOPtrType)) {
705 kind = CheckIOConstructor(
CRD,
"__void__",
nullptr, *
fInterp);
706 if (kind == EIOCtorCategory::kIORefType) {
712 return CheckDefaultConstructor(
CRD, *
fInterp) ? EIOCtorCategory::kDefault : EIOCtorCategory::kAbsent;
719 return fInterp->getLookupHelper()
721 gDebug > 5 ? cling::LookupHelper::WithDiagnostics
722 : cling::LookupHelper::NoDiagnostics);
732 fIter = DeclContext::decl_iterator();
736 const cling::LookupHelper&
lh =
fInterp->getLookupHelper();
738 : cling::LookupHelper::NoDiagnostics,
743 SetDecl(
lh.findScope(buf,
gDebug > 5 ? cling::LookupHelper::WithDiagnostics
744 : cling::LookupHelper::NoDiagnostics,
749 if (
const auto *
TD =
fType->getAsTagDecl()) {
760 fIter = DeclContext::decl_iterator();
768 Fatal(
"TClingClassInfo::Init(tagnum)",
"Should no longer be called");
778 if (
const auto *
TD =
fType->getAsTagDecl()) {
787 Error(
"TClingClassInfo::Init(const Type&)",
788 "The given type %s does not point to a Decl",
806 llvm::dyn_cast<CXXRecordDecl>(
GetDecl());
813 llvm::dyn_cast<CXXRecordDecl>(base.
GetDecl());
830 if (
auto *
ED = llvm::dyn_cast<clang::EnumDecl>(
GetDecl()))
831 return ED->isScoped();
842 if (
auto ED = llvm::dyn_cast<EnumDecl>(
GetDecl())) {
844 auto Ty =
ED->getIntegerType().getTypePtrOrNull();
846 Ty =
Ty->getUnqualifiedDesugaredType();
847 if (
auto BTy = llvm::dyn_cast_or_null<BuiltinType>(
Ty)) {
848 switch (
BTy->getKind()) {
849 case BuiltinType::Bool:
852 case BuiltinType::Char_U:
853 case BuiltinType::UChar:
856 case BuiltinType::Char_S:
857 case BuiltinType::SChar:
860 case BuiltinType::UShort:
862 case BuiltinType::Short:
864 case BuiltinType::UInt:
866 case BuiltinType::Int:
868 case BuiltinType::ULong:
870 case BuiltinType::Long:
872 case BuiltinType::ULongLong:
874 case BuiltinType::LongLong:
902 if (!
CRD->hasDefinition()) {
907 if (
TD &&
TD->getDefinition() ==
nullptr) {
938 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
945 fIter =
DC->noload_decls_begin();
953 llvm::dyn_cast<NamedDecl>(
GetDecl())) {
956 llvm::raw_string_ostream stream(buf);
957 ND->getNameForDiagnostic(stream, Policy,
false);
959 Error(
"TClingClassInfo::InternalNext",
960 "Next called but iteration not prepared for %s!", buf.c_str());
962 Error(
"TClingClassInfo::InternalNext",
963 "Next called but iteration not prepared!");
995 fIter =
DC->noload_decls_begin();
1015 Decl::Kind
DK =
fIter->getKind();
1016 if ((
DK == Decl::Namespace) || (
DK == Decl::Enum) ||
1017 (
DK == Decl::CXXRecord) ||
1018 (
DK == Decl::ClassTemplateSpecialization)) {
1020 if (
TD && !
TD->isCompleteDefinition()) {
1024 if (
DK == Decl::Namespace) {
1026 if (!
fIter->isCanonicalDecl()) {
1032 if (
DK != Decl::Enum) {
1036 || (!
fIterAll && *
DC->noload_decls_begin())) {
1047 Warning(
"TClingClassInfo::Next()",
"Reached an invalid decl.");
1050 llvm::dyn_cast<RecordDecl>(
GetDecl())) {
1051 fType =
RD->getASTContext().getCanonicalTagType(
RD).getTypePtr();
1069 Error(
"TClingClassInfo::New()",
"Called while invalid!");
1073 Error(
"TClingClassInfo::New()",
"Class is not loaded: %s",
1085 Error(
"TClingClassInfo::New()",
"This is a namespace!: %s",
1099 void* obj =
nullptr;
1101 obj =
cf.ExecDefaultConstructor(
this, kind,
type_name,
1104 Error(
"TClingClassInfo::New()",
"Call of default constructor "
1105 "failed to return an object for class: %s",
1118 Error(
"TClingClassInfo::New(n)",
"Called while invalid!");
1122 Error(
"TClingClassInfo::New(n)",
"Class is not loaded: %s",
1135 Error(
"TClingClassInfo::New(n)",
"This is a namespace!: %s",
1149 void* obj =
nullptr;
1151 obj =
cf.ExecDefaultConstructor(
this, kind,
type_name,
1152 nullptr, (
unsigned long)
n);
1154 Error(
"TClingClassInfo::New(n)",
"Call of default constructor "
1155 "failed to return an array of class: %s",
1169 Error(
"TClingClassInfo::New(n, arena)",
"Called while invalid!");
1173 Error(
"TClingClassInfo::New(n, arena)",
"Class is not loaded: %s",
1186 Error(
"TClingClassInfo::New(n, arena)",
"This is a namespace!: %s",
1200 void* obj =
nullptr;
1203 obj =
cf.ExecDefaultConstructor(
this, kind,
type_name,
1204 arena, (
unsigned long)
n);
1214 Error(
"TClingClassInfo::New(arena)",
"Called while invalid!");
1218 Error(
"TClingClassInfo::New(arena)",
"Class is not loaded: %s",
1231 Error(
"TClingClassInfo::New(arena)",
"This is a namespace!: %s",
1245 void* obj =
nullptr;
1248 obj =
cf.ExecDefaultConstructor(
this, kind,
type_name,
1265 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
1267 const clang::DeclContext *
ctxt =
GetDecl()->getDeclContext();
1268 clang::NamespaceDecl *
std_ns =
fInterp->getSema().getStdNamespace();
1269 while (
ctxt && !
ctxt->isTranslationUnit()) {
1277 if ((
DK == Decl::Namespace) || (
DK == Decl::TranslationUnit)) {
1292 llvm::dyn_cast<CXXRecordDecl>(
GetDecl());
1296 if (
CRD->isClass()) {
1298 }
else if (
CRD->isStruct()) {
1300 }
else if (
CRD->isUnion()) {
1303 if (
CRD->hasDefinition() &&
CRD->isAbstract()) {
1337 if (
DK == Decl::Namespace) {
1341 else if (
DK == Decl::Enum) {
1350 if (!
RD->getDefinition()) {
1355 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
1357 int64_t
size = Layout.getSize().getQuantity();
1381 if (
DK == Decl::Namespace) {
1383 }
else if (
DK == Decl::Enum) {
1390 if (!
RD->getDefinition()) {
1395 cling::Interpreter::PushTransactionRAII
RAII(
fInterp);
1397 auto align = Layout.getAlignment().getQuantity();
1433 llvm::dyn_cast<NamedDecl>(
GetDecl())) {
1436 llvm::raw_string_ostream stream(output);
1437 ND->getNameForDiagnostic(stream, Policy,
true);
1458 std::string
attr = A->getAnnotation().str();
1475 llvm::dyn_cast<CXXRecordDecl>(
GetDecl());
1476 if (
CRD && !
CRD->isFromASTFile()) {
1495 buf =
ND->getNameAsString();
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
static std::string FullyQualifiedName(const Decl *decl)
ptrdiff_t(* OffsetPtrFunc_t)(void *, bool)
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.
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
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 attr
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
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 property
R__EXTERN TVirtualMutex * gInterpreterMutex
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
Emulation of the CINT BaseClassInfo class.
Emulation of the CINT CallFunc class.
Emulation of the CINT ClassInfo class.
clang::DeclContext::decl_iterator fIter
static bool IsEnum(cling::Interpreter *interp, const char *name)
long ClassProperty() const
void Init(const char *name)
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
llvm::DenseMap< const clang::Decl *, std::pair< ptrdiff_t, OffsetPtrFunc_t > > fOffsetCache
EDataType GetUnderlyingType() const
size_t GetAlignOf() const
Return the alignment of the class in bytes as reported by clang.
std::mutex fOffsetCacheMutex
const char * TmpltName() const
void AddBaseOffsetValue(const clang::Decl *decl, ptrdiff_t offset)
Longptr_t GetOffset(const clang::CXXMethodDecl *md) const
ptrdiff_t GetBaseOffset(TClingClassInfo *toBase, void *address, bool isDerivedObject)
void SetDecl(const clang::Decl *D)
bool IsScopedEnum() const
ROOT::TMetaUtils::EIOCtorCategory HasDefaultConstructor(bool checkio=false, std::string *type_name=nullptr) const
TClingMethodInfo GetMethodWithArgs(const char *fname, const char *arglist, Longptr_t *poffset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch, EInheritanceMode imode=kWithInheritance) const
const clang::FunctionTemplateDecl * GetFunctionTemplate(const char *fname) const
int GetMethodNArg(const char *method, const char *proto, Bool_t objectIsConst, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool IsValidMethod(const char *method, const char *proto, Bool_t objectIsConst, Longptr_t *offset, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch) const
bool HasMethod(const char *name) const
std::string fDeclFileName
void DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void * New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
TClingMethodInfo GetMethod(const char *fname) const
const clang::ValueDecl * GetDataMember(const char *name) const
int Size() const
Return the size of the class in bytes as reported by clang.
void Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
std::vector< std::string > GetUsingNamespaces()
cling::Interpreter * fInterp
std::vector< clang::DeclContext::decl_iterator > fIterStack
bool IsBase(const char *name) const
const clang::Type * fType
void Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const clang::Decl * fDecl
virtual bool IsValid() const
virtual const clang::Decl * GetDecl() const
Emulation of the CINT MethodInfo class.
constexpr bool IsValidAlignment(std::size_t align) noexcept
Return true if align is a valid C++ alignment value: strictly positive and a power of two.
R__EXTERN TVirtualRWMutex * gCoreMutex
std::string InsertStd(const char *tname)