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)) {
342 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
343 const clang::RecordDecl *RD = FldD->getParent();
344 const clang::ASTRecordLayout &Layout = C.getASTRecordLayout(RD);
345 uint64_t bits = Layout.getFieldOffset(FldD->getFieldIndex());
346 int64_t
offset = C.toCharUnitsFromBits(bits).getQuantity();
349 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
353 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
357 if (VD->hasInit() && (VD->isConstexpr() || VD->getType().isConstQualified())) {
358 if (
const APValue* val = VD->evaluateValue()) {
359 if (VD->getType()->isIntegralType(C)) {
360 return reinterpret_cast<Longptr_t>(val->getInt().getRawData());
364 switch (val->getKind()) {
366 if (val->getInt().isSigned())
373 if (&val->getFloat().getSemantics()
374 == (
const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle()) {
377 }
else if (&val->getFloat().getSemantics()
378 == (
const llvm::fltSemantics*) &llvm::APFloat::IEEEdouble()) {
400 else if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
405 return reinterpret_cast<Longptr_t>(ECD->getInitVal().getRawData());
408 return reinterpret_cast<Longptr_t>(((
char*)ECD->getInitVal().getRawData())+
sizeof(
Longptr_t) );
426 const Decl *thisDecl =
GetDecl();
427 clang::AccessSpecifier strictestAccess = thisDecl->getAccess();
428 const DeclContext *nonTransparentDC = thisDecl->getDeclContext();
430 auto getParentAccessAndNonTransparentDC = [&]() {
431 const Decl *declOrParent = thisDecl;
432 for (
const auto *Parent = declOrParent->getDeclContext(); !llvm::isa<TranslationUnitDecl>(Parent);
433 Parent = declOrParent->getDeclContext()) {
434 if (!Parent->isTransparentContext()) {
435 if (
const auto *RD = llvm::dyn_cast<clang::RecordDecl>(Parent)) {
436 if (!RD->isAnonymousStructOrUnion()) {
437 nonTransparentDC = RD;
441 nonTransparentDC = Parent;
446 declOrParent = llvm::dyn_cast<clang::Decl>(Parent);
449 if (strictestAccess < declOrParent->getAccess()) {
450 strictestAccess = declOrParent->getAccess();
455 getParentAccessAndNonTransparentDC();
459 switch (strictestAccess) {
460 case clang::AS_public:
463 case clang::AS_protected:
466 case clang::AS_private:
474 assert(
false &&
"Unexpected value for the access property value in Clang");
477 if (llvm::isa<clang::UsingShadowDecl>(thisDecl))
481 if (
const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(vd)) {
482 if (vard->isConstexpr())
484 if (vard->getStorageClass() == clang::SC_Static) {
486 }
else if (nonTransparentDC->isNamespace()) {
491 }
else if (llvm::isa<clang::EnumConstantDecl>(vd)) {
496 clang::QualType qt = vd->getType();
497 if (llvm::isa<clang::TypedefType>(qt)) {
500 qt = qt.getCanonicalType();
502 const clang::TagType *
tt = qt->getAs<clang::TagType>();
505 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
506 const clang::TagDecl *td =
tt->getDecl();
510 else if (td->isStruct()) {
513 else if (td->isUnion()) {
516 else if (td->isEnum()) {
521 if (
const auto *RD = llvm::dyn_cast<RecordDecl>(thisDecl->getDeclContext())) {
538 clang::QualType qt = vd->getType();
550 clang::Decl::Kind dk = vd->getKind();
551 if ((dk != clang::Decl::Field) && (dk != clang::Decl::Var) &&
552 (dk != clang::Decl::EnumConstant)) {
556 clang::QualType qt = vd->getType();
557 if (qt->isIncompleteType()) {
561 clang::ASTContext &context =
GetDecl()->getASTContext();
563 return static_cast<int>(context.getTypeSizeInChars(qt).getQuantity());
576 static std::string buf;
579 clang::QualType vdType = vd->getType();
582 while (vdType->isArrayType()) {
583 vdType =
GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
604 static std::string buf;
615 while (buf.length() && buf[buf.length()-1] ==
']') {
616 size_t last = buf.rfind(
'[');
617 if (last != std::string::npos) {
646 bool titleFound=
false;
648 std::string attribute_s;
650 for (Decl::attr_iterator attrIt = decl->attr_begin();
651 attrIt!=decl->attr_end() && !titleFound ;++attrIt){
659 if (!titleFound && !decl->isFromASTFile()) {
675 return llvm::StringRef();
677 const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(
GetTargetValueDecl());
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 Atom_t Time_t property
R__EXTERN TVirtualMutex * gInterpreterMutex
#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
union TClingDataMemberInfo::@28 fConstInitVal
const clang::UsingShadowDecl * GetAsUsingShadowDecl() const
int MaxIndex(int dim) const
TClingDataMemberInfo(cling::Interpreter *interp)
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)