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());
107 auto *DC = llvm::dyn_cast<clang::DeclContext>(ci->
GetDecl());
114 const clang::ValueDecl *ValD,
119 using namespace llvm;
120 const auto DC = ValD->getDeclContext();
122 assert((ci || isa<TranslationUnitDecl>(DC) ||
123 ((DC->isTransparentContext() || DC->isInlineNamespace()) && isa<TranslationUnitDecl>(DC->getParent()) ) ||
124 isa<EnumConstantDecl>(ValD)) &&
"Not TU?");
125 assert(IsRelevantKind(ValD->getKind()) &&
126 "The decl should be either VarDecl or FieldDecl or EnumConstDecl");
139 if (code == 0)
return;
154 return (
const clang::Decl*)(VD->getCanonicalDecl());
160 return dyn_cast<ValueDecl>(
GetDecl());
165 return dyn_cast<UsingShadowDecl>(
GetDecl());
172 if (
auto VD = dyn_cast<ValueDecl>(D))
174 }
while ((D = dyn_cast<UsingShadowDecl>(D)->getTargetDecl()));
189 clang::Decl::Kind DK = VD->getKind();
191 (DK != clang::Decl::Field) &&
193 (DK != clang::Decl::EnumConstant)
198 if (DK == clang::Decl::EnumConstant) {
204 clang::QualType QT = VD->getType().getCanonicalType();
207 if (QT->isArrayType()) {
209 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
212 else if (QT->isReferenceType()) {
213 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
216 else if (QT->isPointerType()) {
217 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
220 else if (QT->isMemberPointerType()) {
221 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
236 clang::Decl::Kind DK =
GetDecl()->getKind();
238 (DK != clang::Decl::Field) &&
240 (DK != clang::Decl::EnumConstant)
245 if (DK == clang::Decl::EnumConstant) {
251 clang::QualType QT = VD->getType().getCanonicalType();
253 if ((dim < 0) || (dim >= paran)) {
260 if (QT->isArrayType()) {
262 if (
const clang::ConstantArrayType *CAT =
263 llvm::dyn_cast<clang::ConstantArrayType>(QT)
265 max =
static_cast<int>(CAT->getSize().getZExtValue());
267 else if (llvm::dyn_cast<clang::IncompleteArrayType>(QT)) {
276 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
279 else if (QT->isReferenceType()) {
280 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
283 else if (QT->isPointerType()) {
284 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
287 else if (QT->isMemberPointerType()) {
288 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
298 assert(!
fDecl &&
"This is a single decl, not an iterator!");
318 using namespace clang;
325 ASTContext&
C = D->getASTContext();
326 if (
const FieldDecl *FldD = dyn_cast<FieldDecl>(D)) {
328 const clang::RecordDecl *RD = FldD->getParent();
329 const clang::ASTRecordLayout &
Layout =
C.getASTRecordLayout(RD);
330 uint64_t bits =
Layout.getFieldOffset(FldD->getFieldIndex());
331 int64_t offset =
C.toCharUnitsFromBits(bits).getQuantity();
332 return static_cast<long>(offset);
334 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
338 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
340 if (
long addr =
reinterpret_cast<long>(
fInterp->getAddressOfGlobal(GlobalDecl(VD))))
342 auto evalStmt = VD->ensureEvaluatedStmt();
343 if (evalStmt && evalStmt->Value) {
344 if (
const APValue* val = VD->evaluateValue()) {
345 if (VD->getType()->isIntegralType(
C)) {
346 return reinterpret_cast<long>(val->getInt().getRawData());
350 switch (val->getKind()) {
352 if (val->getInt().isSigned())
359 if (&val->getFloat().getSemantics()
360 == (
const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle()) {
363 }
else if (&val->getFloat().getSemantics()
364 == (
const llvm::fltSemantics*) &llvm::APFloat::IEEEdouble()) {
382 else if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
387 return reinterpret_cast<long>(ECD->getInitVal().getRawData());
390 return reinterpret_cast<long>(((
char*)ECD->getInitVal().getRawData())+
sizeof(
long) );
408 const Decl *thisDecl =
GetDecl();
409 clang::AccessSpecifier strictestAccess = thisDecl->getAccess();
410 const DeclContext *nonTransparentDC = thisDecl->getDeclContext();
412 auto getParentAccessAndNonTransparentDC = [&]() {
413 const Decl *declOrParent = thisDecl;
414 for (
const auto *Parent = declOrParent->getDeclContext(); !llvm::isa<TranslationUnitDecl>(Parent);
415 Parent = declOrParent->getDeclContext()) {
416 if (!Parent->isTransparentContext()) {
417 if (
const auto *RD = llvm::dyn_cast<clang::RecordDecl>(Parent)) {
418 if (!RD->isAnonymousStructOrUnion()) {
419 nonTransparentDC = RD;
423 nonTransparentDC = Parent;
428 declOrParent = llvm::dyn_cast<clang::Decl>(Parent);
429 if (strictestAccess < declOrParent->getAccess()) {
430 strictestAccess = declOrParent->getAccess();
435 getParentAccessAndNonTransparentDC();
437 switch (strictestAccess) {
438 case clang::AS_public:
441 case clang::AS_protected:
444 case clang::AS_private:
454 if (llvm::isa<clang::UsingShadowDecl>(thisDecl))
458 if (
const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(vd)) {
459 if (vard->isConstexpr())
461 if (vard->getStorageClass() == clang::SC_Static) {
463 }
else if (nonTransparentDC->isNamespace()) {
468 }
else if (llvm::isa<clang::EnumConstantDecl>(vd)) {
473 clang::QualType qt = vd->getType();
474 if (llvm::isa<clang::TypedefType>(qt)) {
477 qt = qt.getCanonicalType();
479 const clang::TagType *
tt = qt->getAs<clang::TagType>();
481 const clang::TagDecl *td =
tt->getDecl();
485 else if (td->isStruct()) {
488 else if (td->isUnion()) {
491 else if (td->isEnum()) {
496 if (
const auto *RD = llvm::dyn_cast<RecordDecl>(thisDecl->getDeclContext())) {
513 clang::QualType qt = vd->getType();
525 clang::Decl::Kind dk = vd->getKind();
527 (dk != clang::Decl::EnumConstant)) {
531 clang::QualType qt = vd->getType();
532 if (qt->isIncompleteType()) {
536 clang::ASTContext &context =
GetDecl()->getASTContext();
538 return static_cast<int>(context.getTypeSizeInChars(qt).getQuantity());
551 static std::string buf;
554 clang::QualType vdType = vd->getType();
557 while (vdType->isArrayType()) {
558 vdType =
GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
579 static std::string buf;
590 while (buf.length() && buf[buf.length()-1] ==
']') {
591 size_t last = buf.rfind(
'[');
592 if (last != std::string::npos) {
621 bool titleFound=
false;
623 std::string attribute_s;
625 for (Decl::attr_iterator attrIt = decl->attr_begin();
626 attrIt!=decl->attr_end() && !titleFound ;++attrIt){
634 if (!titleFound && !decl->isFromASTFile()) {
650 return llvm::StringRef();
652 const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(
GetTargetValueDecl());
654 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
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
TClingClassInfo * fClassInfo
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)
RooCmdArg Layout(Double_t xmin, Double_t xmax=0.99, Double_t ymin=0.95)
Type
enumeration specifying the integration types.
double Var(const RVec< T > &v)
Get the variance of the elements of an RVec.
static constexpr double L