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 <CppInterOp/CppInterOp.h>
48#include "llvm/Support/Casting.h"
49#include "llvm/Support/raw_ostream.h"
50#include "llvm/ADT/APSInt.h"
51#include "llvm/ADT/APFloat.h"
56 static bool IsRelevantKind(clang::Decl::Kind DK)
58 return DK == clang::Decl::Field || DK == clang::Decl::EnumConstant || DK == clang::Decl::Var;
67 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D)) {
74 if (!ND->getIdentifier())
81 return !IsRelevantKind(D->getKind());
89 if (
auto *VD = llvm::dyn_cast<clang::ValueDecl>(USD->getTargetDecl())) {
90 return !IsRelevantKind(VD->getKind());
115 auto *DC = llvm::dyn_cast<clang::DeclContext>(ci->
GetDecl());
122 const clang::ValueDecl *ValD,
133 using namespace llvm;
134 const auto DC = ValD->getDeclContext();
136 assert((ci || isa<TranslationUnitDecl>(DC) ||
137 ((DC->isTransparentContext() || DC->isInlineNamespace()) && isa<TranslationUnitDecl>(DC->getParent()) ) ||
138 isa<EnumConstantDecl>(ValD)) &&
"Not TU?");
139 assert(IsRelevantKind(ValD->getKind()) &&
140 "The decl should be either VarDecl or FieldDecl or EnumConstDecl");
153 if (code == 0)
return;
168 return (
const clang::Decl*)(VD->getCanonicalDecl());
174 return dyn_cast<ValueDecl>(
GetDecl());
179 return dyn_cast<UsingShadowDecl>(
GetDecl());
186 if (
auto VD = dyn_cast<ValueDecl>(D))
188 }
while ((D = dyn_cast<UsingShadowDecl>(D)->getTargetDecl()));
203 clang::Decl::Kind DK = VD->getKind();
205 (DK != clang::Decl::Field) &&
206 (DK != clang::Decl::Var) &&
207 (DK != clang::Decl::EnumConstant)
212 if (DK == clang::Decl::EnumConstant) {
218 clang::QualType QT = VD->getType().getCanonicalType();
221 if (QT->isArrayType()) {
223 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
226 else if (QT->isReferenceType()) {
227 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
230 else if (QT->isPointerType()) {
231 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
234 else if (QT->isMemberPointerType()) {
235 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
250 clang::Decl::Kind DK =
GetDecl()->getKind();
252 (DK != clang::Decl::Field) &&
253 (DK != clang::Decl::Var) &&
254 (DK != clang::Decl::EnumConstant)
259 if (DK == clang::Decl::EnumConstant) {
265 clang::QualType QT = VD->getType().getCanonicalType();
267 if ((dim < 0) || (dim >= paran)) {
274 if (QT->isArrayType()) {
276 if (
const clang::ConstantArrayType *CAT =
277 llvm::dyn_cast<clang::ConstantArrayType>(QT)
279 max =
static_cast<int>(CAT->getSize().getZExtValue());
281 else if (llvm::dyn_cast<clang::IncompleteArrayType>(QT)) {
290 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
293 else if (QT->isReferenceType()) {
294 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
297 else if (QT->isPointerType()) {
298 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
301 else if (QT->isMemberPointerType()) {
302 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
312 assert(!
fDecl &&
"This is a single decl, not an iterator!");
327 return fIter.IsValid();
332 using namespace clang;
339 ASTContext& C = D->getASTContext();
340 if (
const FieldDecl *FldD = dyn_cast<FieldDecl>(D)) {
344 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
345 const clang::RecordDecl *RD = FldD->getParent();
346 const clang::ASTRecordLayout &Layout = C.getASTRecordLayout(RD);
347 uint64_t bits = Layout.getFieldOffset(FldD->getFieldIndex());
348 int64_t offset = C.toCharUnitsFromBits(bits).getQuantity();
351 else if (
const VarDecl *VD = dyn_cast<VarDecl>(D)) {
355 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
359 if (VD->hasInit() && (VD->isConstexpr() || VD->getType().isConstQualified())) {
360 if (
const APValue* val = VD->evaluateValue()) {
361 if (VD->getType()->isIntegralType(C)) {
362 return reinterpret_cast<Longptr_t>(val->getInt().getRawData());
366 switch (val->getKind()) {
368 if (val->getInt().isSigned())
375 if (&val->getFloat().getSemantics()
376 == (
const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle()) {
379 }
else if (&val->getFloat().getSemantics()
380 == (
const llvm::fltSemantics*) &llvm::APFloat::IEEEdouble()) {
402 else if (
const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
410 auto v = ECD->getInitVal();
411 if (
v.getActiveBits() == 64 &&
v.isUnsigned()) {
413 fEnumValue =
static_cast<int64_t
>(
v.getZExtValue());
435 const Decl *thisDecl =
GetDecl();
436 clang::AccessSpecifier strictestAccess = thisDecl->getAccess();
437 const DeclContext *nonTransparentDC = thisDecl->getDeclContext();
439 auto getParentAccessAndNonTransparentDC = [&]() {
440 const Decl *declOrParent = thisDecl;
441 for (
const auto *Parent = declOrParent->getDeclContext(); !llvm::isa<TranslationUnitDecl>(Parent);
442 Parent = declOrParent->getDeclContext()) {
443 if (!Parent->isTransparentContext()) {
444 if (
const auto *RD = llvm::dyn_cast<clang::RecordDecl>(Parent)) {
445 if (!RD->isAnonymousStructOrUnion()) {
446 nonTransparentDC = RD;
450 nonTransparentDC = Parent;
455 declOrParent = llvm::dyn_cast<clang::Decl>(Parent);
458 if (strictestAccess < declOrParent->getAccess()) {
459 strictestAccess = declOrParent->getAccess();
464 getParentAccessAndNonTransparentDC();
468 switch (strictestAccess) {
469 case clang::AS_public:
472 case clang::AS_protected:
475 case clang::AS_private:
483 assert(
false &&
"Unexpected value for the access property value in Clang");
486 if (llvm::isa<clang::UsingShadowDecl>(thisDecl))
490 if (
const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(vd)) {
491 if (vard->isConstexpr())
493 if (vard->getStorageClass() == clang::SC_Static) {
495 }
else if (nonTransparentDC->isNamespace()) {
500 }
else if (llvm::isa<clang::EnumConstantDecl>(vd)) {
505 clang::QualType qt = vd->getType();
506 if (llvm::isa<clang::TypedefType>(qt)) {
509 qt = qt.getCanonicalType();
511 const clang::TagType *
tt = qt->getAs<clang::TagType>();
514 cling::Interpreter::PushTransactionRAII RAII(
fInterp);
515 const clang::TagDecl *td =
tt->getDecl();
519 else if (td->isStruct()) {
522 else if (td->isUnion()) {
525 else if (td->isEnum()) {
530 if (
const auto *RD = llvm::dyn_cast<RecordDecl>(thisDecl->getDeclContext())) {
547 clang::QualType qt = vd->getType();
559 clang::Decl::Kind dk = vd->getKind();
560 if ((dk != clang::Decl::Field) && (dk != clang::Decl::Var) &&
561 (dk != clang::Decl::EnumConstant)) {
565 return Cpp::GetSizeOfType(vd->getType().getAsOpaquePtr());
578 static std::string buf;
581 clang::QualType vdType = vd->getType();
584 while (vdType->isArrayType()) {
585 vdType =
GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
606 static std::string buf;
617 while (buf.length() && buf[buf.length()-1] ==
']') {
618 size_t last = buf.rfind(
'[');
619 if (last != std::string::npos) {
648 bool titleFound=
false;
650 std::string attribute_s;
652 for (Decl::attr_iterator attrIt = decl->attr_begin();
653 attrIt!=decl->attr_end() && !titleFound ;++attrIt){
661 if (!titleFound && !decl->isFromASTFile()) {
677 return llvm::StringRef();
679 const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(
GetTargetValueDecl());
long Longptr_t
Integer large enough to hold a pointer (platform-dependent).
externTVirtualMutex * gInterpreterMutex
#define R__LOCKGUARD(mutex)
Emulation of the CINT ClassInfo class.
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
union TClingDataMemberInfo::@235010322372054014261023174274306140311344130372 fConstInitVal
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
Emulation of the CINT TypeInfo class.
static bool WantsRegularMembers(EMemberSelection sel)
EMemberSelection
Kinds of members to include in lists.
static bool WantsUsingDecls(EMemberSelection sel)