34#include "cling/Interpreter/Interpreter.h"
36#include "clang/AST/Attr.h"
37#include "clang/AST/ASTContext.h"
38#include "clang/AST/Decl.h"
39#include "clang/AST/GlobalDecl.h"
40#include "clang/AST/Expr.h"
41#include "clang/AST/ExprCXX.h"
42#include "clang/AST/PrettyPrinter.h"
43#include "clang/AST/RecordLayout.h"
44#include "clang/AST/Type.h"
46#include "llvm/Support/Casting.h"
47#include "llvm/Support/raw_ostream.h"
48#include "llvm/ADT/APSInt.h"
49#include "llvm/ADT/APFloat.h"
54 static bool IsRelevantKind(clang::Decl::Kind DK)
56 return DK == clang::Decl::Field || DK == clang::Decl::EnumConstant || DK == clang::Decl::Var;
65 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D)) {
72 if (!ND->getIdentifier())
79 return !IsRelevantKind(D->getKind());
87 if (
auto *VD = llvm::dyn_cast<clang::ValueDecl>(USD->getTargetDecl())) {
88 return !IsRelevantKind(VD->getKind());
113 auto *DC = llvm::dyn_cast<clang::DeclContext>(ci->
GetDecl());
120 const clang::ValueDecl *ValD,
131 using namespace llvm;
132 const auto DC = ValD->getDeclContext();
134 assert((ci || isa<TranslationUnitDecl>(DC) ||
135 ((DC->isTransparentContext() || DC->isInlineNamespace()) && isa<TranslationUnitDecl>(DC->getParent()) ) ||
136 isa<EnumConstantDecl>(ValD)) &&
"Not TU?");
137 assert(IsRelevantKind(ValD->getKind()) &&
138 "The decl should be either VarDecl or FieldDecl or EnumConstDecl");
151 if (code == 0)
return;
166 return (
const clang::Decl*)(VD->getCanonicalDecl());
172 return dyn_cast<ValueDecl>(
GetDecl());
177 return dyn_cast<UsingShadowDecl>(
GetDecl());
184 if (
auto VD = dyn_cast<ValueDecl>(D))
186 }
while ((D = dyn_cast<UsingShadowDecl>(D)->getTargetDecl()));
201 clang::Decl::Kind DK = VD->getKind();
203 (DK != clang::Decl::Field) &&
204 (DK != clang::Decl::Var) &&
205 (DK != clang::Decl::EnumConstant)
210 if (DK == clang::Decl::EnumConstant) {
216 clang::QualType QT = VD->getType().getCanonicalType();
219 if (QT->isArrayType()) {
221 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
224 else if (QT->isReferenceType()) {
225 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
228 else if (QT->isPointerType()) {
229 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
232 else if (QT->isMemberPointerType()) {
233 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
248 clang::Decl::Kind DK =
GetDecl()->getKind();
250 (DK != clang::Decl::Field) &&
251 (DK != clang::Decl::Var) &&
252 (DK != clang::Decl::EnumConstant)
257 if (DK == clang::Decl::EnumConstant) {
263 clang::QualType QT = VD->getType().getCanonicalType();
265 if ((dim < 0) || (dim >= paran)) {
272 if (QT->isArrayType()) {
274 if (
const clang::ConstantArrayType *CAT =
275 llvm::dyn_cast<clang::ConstantArrayType>(QT)
277 max =
static_cast<int>(CAT->getSize().getZExtValue());
279 else if (llvm::dyn_cast<clang::IncompleteArrayType>(QT)) {
288 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
291 else if (QT->isReferenceType()) {
292 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
295 else if (QT->isPointerType()) {
296 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
299 else if (QT->isMemberPointerType()) {
300 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
310 assert(!
fDecl &&
"This is a single decl, not an iterator!");
330 using namespace clang;
337 ASTContext& C = D->getASTContext();
338 if (
const FieldDecl *FldD = dyn_cast<FieldDecl>(D)) {
340 const clang::RecordDecl *RD = FldD->getParent();
341 const clang::ASTRecordLayout &Layout = C.getASTRecordLayout(RD);
342 uint64_t bits = Layout.getFieldOffset(FldD->getFieldIndex());
343 int64_t offset = C.toCharUnitsFromBits(bits).getQuantity();
344 return static_cast<long>(offset);
346 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
350 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
352 if (
long addr =
reinterpret_cast<long>(
fInterp->getAddressOfGlobal(GlobalDecl(VD))))
354 auto evalStmt = VD->ensureEvaluatedStmt();
355 if (evalStmt && evalStmt->Value) {
356 if (
const APValue* val = VD->evaluateValue()) {
357 if (VD->getType()->isIntegralType(C)) {
358 return reinterpret_cast<long>(val->getInt().getRawData());
362 switch (val->getKind()) {
364 if (val->getInt().isSigned())
371 if (&val->getFloat().getSemantics()
372 == (
const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle()) {
375 }
else if (&val->getFloat().getSemantics()
376 == (
const llvm::fltSemantics*) &llvm::APFloat::IEEEdouble()) {
394 else if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
399 return reinterpret_cast<long>(ECD->getInitVal().getRawData());
402 return reinterpret_cast<long>(((
char*)ECD->getInitVal().getRawData())+
sizeof(
long) );
420 const Decl *thisDecl =
GetDecl();
421 clang::AccessSpecifier strictestAccess = thisDecl->getAccess();
422 const DeclContext *nonTransparentDC = thisDecl->getDeclContext();
424 auto getParentAccessAndNonTransparentDC = [&]() {
425 const Decl *declOrParent = thisDecl;
426 for (
const auto *Parent = declOrParent->getDeclContext(); !llvm::isa<TranslationUnitDecl>(Parent);
427 Parent = declOrParent->getDeclContext()) {
428 if (!Parent->isTransparentContext()) {
429 if (
const auto *RD = llvm::dyn_cast<clang::RecordDecl>(Parent)) {
430 if (!RD->isAnonymousStructOrUnion()) {
431 nonTransparentDC = RD;
435 nonTransparentDC = Parent;
440 declOrParent = llvm::dyn_cast<clang::Decl>(Parent);
441 if (strictestAccess < declOrParent->getAccess()) {
442 strictestAccess = declOrParent->getAccess();
447 getParentAccessAndNonTransparentDC();
449 switch (strictestAccess) {
450 case clang::AS_public:
453 case clang::AS_protected:
456 case clang::AS_private:
466 if (llvm::isa<clang::UsingShadowDecl>(thisDecl))
470 if (
const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(vd)) {
471 if (vard->isConstexpr())
473 if (vard->getStorageClass() == clang::SC_Static) {
475 }
else if (nonTransparentDC->isNamespace()) {
480 }
else if (llvm::isa<clang::EnumConstantDecl>(vd)) {
485 clang::QualType qt = vd->getType();
486 if (llvm::isa<clang::TypedefType>(qt)) {
489 qt = qt.getCanonicalType();
491 const clang::TagType *
tt = qt->getAs<clang::TagType>();
494 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
495 const clang::TagDecl *td =
tt->getDecl();
499 else if (td->isStruct()) {
502 else if (td->isUnion()) {
505 else if (td->isEnum()) {
510 if (
const auto *RD = llvm::dyn_cast<RecordDecl>(thisDecl->getDeclContext())) {
527 clang::QualType qt = vd->getType();
539 clang::Decl::Kind dk = vd->getKind();
540 if ((dk != clang::Decl::Field) && (dk != clang::Decl::Var) &&
541 (dk != clang::Decl::EnumConstant)) {
545 clang::QualType qt = vd->getType();
546 if (qt->isIncompleteType()) {
550 clang::ASTContext &context =
GetDecl()->getASTContext();
552 return static_cast<int>(context.getTypeSizeInChars(qt).getQuantity());
565 static std::string buf;
568 clang::QualType vdType = vd->getType();
571 while (vdType->isArrayType()) {
572 vdType =
GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
593 static std::string buf;
604 while (buf.length() && buf[buf.length()-1] ==
']') {
605 size_t last = buf.rfind(
'[');
606 if (last != std::string::npos) {
635 bool titleFound=
false;
637 std::string attribute_s;
639 for (Decl::attr_iterator attrIt = decl->attr_begin();
640 attrIt!=decl->attr_end() && !titleFound ;++attrIt){
648 if (!titleFound && !decl->isFromASTFile()) {
664 return llvm::StringRef();
666 const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(
GetTargetValueDecl());
668 else return llvm::StringRef();
R__EXTERN TVirtualMutex * gInterpreterMutex
typedef void((*Func_t)())
#define R__LOCKGUARD(mutex)
Emulation of the CINT ClassInfo class.
const clang::Type * GetType() const
TClingClassInfo fClassInfo
const char * TypeName() const
const clang::Type * GetClassAsType() const
const clang::Decl * GetDecl() const override
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
void CheckForIoTypeAndName() const
const clang::UsingShadowDecl * GetAsUsingShadowDecl() const
int MaxIndex(int dim) const
TClingDataMemberInfo(cling::Interpreter *interp)
union TClingDataMemberInfo::@29 fConstInitVal
cling::Interpreter * fInterp
const clang::ValueDecl * GetTargetValueDecl() const
Get the ValueDecl, or if this represents a UsingShadowDecl, the underlying target ValueDecl.
const clang::ValueDecl * GetAsValueDecl() const
llvm::StringRef ValidArrayIndex() const
const char * Name() const override
long TypeProperty() const
TClingDataMemberIter fIter
DeclId_t GetDeclId() const
Iterate over VarDecl, FieldDecl, EnumConstantDecl, IndirectFieldDecl, and UsingShadowDecls thereof,...
TDictionary::EMemberSelection fSelection
bool ShouldSkip(const clang::Decl *FD) const final
const clang::Decl * fDecl
virtual const char * Name() const
virtual bool IsValid() const
long Property(long property, clang::QualType &qt) const
virtual const clang::Decl * GetDecl() const
bool Next()
Advance to next non-skipped; return false if no next decl exists.
virtual bool IsValid() const
Emulation of the CINT TypeInfo class.
static bool WantsRegularMembers(EMemberSelection sel)
EMemberSelection
Kinds of members to include in lists.
static bool WantsUsingDecls(EMemberSelection sel)