Logo ROOT  
Reference Guide
TClingDataMemberInfo.cxx
Go to the documentation of this file.
1// @(#)root/core/meta:$Id$
2// Author: Paul Russo 30/07/2012
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/** \class TClingDataMemberInfo
13
14Emulation of the CINT DataMemberInfo class.
15
16The CINT C++ interpreter provides an interface to metadata about
17the data members of a class through the DataMemberInfo class. This
18class provides the same functionality, using an interface as close
19as possible to DataMemberInfo but the data member metadata comes
20from the Clang C++ compiler, not CINT.
21*/
22
24
25#include "TDictionary.h"
26#include "TClingClassInfo.h"
27#include "TClingTypeInfo.h"
28#include "TClingUtils.h"
29#include "TClassEdit.h"
30#include "TError.h"
31#include "TInterpreter.h"
32#include "TVirtualMutex.h"
33
34#include "cling/Interpreter/Interpreter.h"
35
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"
45
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"
50
51using namespace clang;
52
53namespace {
54 static bool IsRelevantKind(clang::Decl::Kind DK)
55 {
56 return DK == clang::Decl::Field || DK == clang::Decl::EnumConstant || DK == clang::Decl::Var;
57 }
58}
59
60bool TClingDataMemberIter::ShouldSkip(const clang::Decl *D) const
61{
63 return true;
64
65 if (const auto *ND = llvm::dyn_cast<NamedDecl>(D)) {
66 // Skip unnamed declarations, e.g. in
67 // struct S {
68 // struct { int i; }
69 // };
70 // the inner struct corresponds to an unnamed member variable,
71 // where only `S::i` should be exposed.
72 if (!ND->getIdentifier())
73 return true;
74 } else {
75 // TClingDataMemberIter only cares about NamedDecls.
76 return true;
77 }
78
79 return !IsRelevantKind(D->getKind());
80}
81
82bool TClingDataMemberIter::ShouldSkip(const clang::UsingShadowDecl *USD) const
83{
85 return true;
86
87 if (auto *VD = llvm::dyn_cast<clang::ValueDecl>(USD->getTargetDecl())) {
88 return !IsRelevantKind(VD->getKind());
89 }
90
91 // TODO: handle multi-level UsingShadowDecls.
92 return true;
93}
94
98: TClingDeclInfo(nullptr), fInterp(interp)
99{
100
102
103 if (ci) {
104 fClassInfo = *ci;
105 } else {
106 fClassInfo = TClingClassInfo(interp);
107 }
108
109 if (!ci || !ci->IsValid()) {
110 return;
111 }
112
113 auto *DC = llvm::dyn_cast<clang::DeclContext>(ci->GetDecl());
114
115 fIter = TClingDataMemberIter(interp, DC, selection);
116 fIter.Init();
117}
118
120 const clang::ValueDecl *ValD,
121 TClingClassInfo *ci)
122: TClingDeclInfo(ValD), fInterp(interp)
123{
124
125 if (ci) {
126 fClassInfo = *ci;
127 } else {
128 fClassInfo = TClingClassInfo(interp);
129 }
130
131 using namespace llvm;
132 const auto DC = ValD->getDeclContext();
133 (void)DC;
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");
139
140}
141
143{
144 // Three cases:
145 // 1) 00: none to be checked
146 // 2) 01: type to be checked
147 // 3) 10: none to be checked
148 // 4) 11: both to be checked
149 unsigned int code = fIoType.empty() + (int(fIoName.empty()) << 1);
150
151 if (code == 0) return;
152
153 const Decl* decl = GetTargetValueDecl();
154
155 if (code == 3 || code == 2) ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",fIoName);
156 if (code == 3 || code == 1) ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"iotype",fIoType);
157
158}
159
161{
162 if (!IsValid()) {
163 return TDictionary::DeclId_t();
164 }
165 if (auto *VD = GetAsValueDecl())
166 return (const clang::Decl*)(VD->getCanonicalDecl());
167 return (const clang::Decl*)(GetAsUsingShadowDecl()->getCanonicalDecl());
168}
169
170const clang::ValueDecl *TClingDataMemberInfo::GetAsValueDecl() const
171{
172 return dyn_cast<ValueDecl>(GetDecl());
173}
174
175const clang::UsingShadowDecl *TClingDataMemberInfo::GetAsUsingShadowDecl() const
176{
177 return dyn_cast<UsingShadowDecl>(GetDecl());
178}
179
180const clang::ValueDecl *TClingDataMemberInfo::GetTargetValueDecl() const
181{
182 const Decl *D = GetDecl();
183 do {
184 if (auto VD = dyn_cast<ValueDecl>(D))
185 return VD;
186 } while ((D = dyn_cast<UsingShadowDecl>(D)->getTargetDecl()));
187 return nullptr;
188}
189
191 return fClassInfo.GetType();
192}
193
195{
196 if (!IsValid()) {
197 return -1;
198 }
199 const clang::ValueDecl *VD = GetTargetValueDecl();
200 // Sanity check the current data member.
201 clang::Decl::Kind DK = VD->getKind();
202 if (
203 (DK != clang::Decl::Field) &&
204 (DK != clang::Decl::Var) &&
205 (DK != clang::Decl::EnumConstant)
206 ) {
207 // Error, was not a data member, variable, or enumerator.
208 return -1;
209 }
210 if (DK == clang::Decl::EnumConstant) {
211 // We know that an enumerator value does not have array type.
212 return 0;
213 }
214 // To get this information we must count the number
215 // of array type nodes in the canonical type chain.
216 clang::QualType QT = VD->getType().getCanonicalType();
217 int cnt = 0;
218 while (1) {
219 if (QT->isArrayType()) {
220 ++cnt;
221 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
222 continue;
223 }
224 else if (QT->isReferenceType()) {
225 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
226 continue;
227 }
228 else if (QT->isPointerType()) {
229 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
230 continue;
231 }
232 else if (QT->isMemberPointerType()) {
233 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
234 continue;
235 }
236 break;
237 }
238 return cnt;
239}
240
242{
243 if (!IsValid()) {
244 return -1;
245 }
246 const clang::ValueDecl *VD = GetTargetValueDecl();
247 // Sanity check the current data member.
248 clang::Decl::Kind DK = GetDecl()->getKind();
249 if (
250 (DK != clang::Decl::Field) &&
251 (DK != clang::Decl::Var) &&
252 (DK != clang::Decl::EnumConstant)
253 ) {
254 // Error, was not a data member, variable, or enumerator.
255 return -1;
256 }
257 if (DK == clang::Decl::EnumConstant) {
258 // We know that an enumerator value does not have array type.
259 return 0;
260 }
261 // To get this information we must count the number
262 // of array type nodes in the canonical type chain.
263 clang::QualType QT = VD->getType().getCanonicalType();
264 int paran = ArrayDim();
265 if ((dim < 0) || (dim >= paran)) {
266 // Passed dimension is out of bounds.
267 return -1;
268 }
269 int cnt = dim;
270 int max = 0;
271 while (1) {
272 if (QT->isArrayType()) {
273 if (cnt == 0) {
274 if (const clang::ConstantArrayType *CAT =
275 llvm::dyn_cast<clang::ConstantArrayType>(QT)
276 ) {
277 max = static_cast<int>(CAT->getSize().getZExtValue());
278 }
279 else if (llvm::dyn_cast<clang::IncompleteArrayType>(QT)) {
280 max = INT_MAX;
281 }
282 else {
283 max = -1;
284 }
285 break;
286 }
287 --cnt;
288 QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
289 continue;
290 }
291 else if (QT->isReferenceType()) {
292 QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
293 continue;
294 }
295 else if (QT->isPointerType()) {
296 QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
297 continue;
298 }
299 else if (QT->isMemberPointerType()) {
300 QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
301 continue;
302 }
303 break;
304 }
305 return max;
306}
307
309{
310 assert(!fDecl && "This is a single decl, not an iterator!");
311
312 ClearNames();
313
314 if (!fFirstTime && !fIter.IsValid()) {
315 // Iterator is already invalid.
316 return 0;
317 }
318 // Advance to the next decl.
319 if (fFirstTime) {
320 // The cint semantics are weird.
321 fFirstTime = false;
322 } else {
323 fIter.Next();
324 }
325 return fIter.IsValid();
326}
327
329{
330 using namespace clang;
331
332 if (!IsValid()) {
333 return -1L;
334 }
335
336 const ValueDecl *D = GetTargetValueDecl();
337 ASTContext& C = D->getASTContext();
338 if (const FieldDecl *FldD = dyn_cast<FieldDecl>(D)) {
339 // The current member is a non-static data member.
340
341 // getASTRecordLayout() might deserialize.
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();
347 return static_cast<Longptr_t>(offset);
348 }
349 else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
350 // Could trigger deserialization of decls, in particular in case
351 // of constexpr, like:
352 // static constexpr Long64_t something = std::numeric_limits<Long64_t>::max();
353 cling::Interpreter::PushTransactionRAII RAII(fInterp);
354
355 if (Longptr_t addr = reinterpret_cast<Longptr_t>(fInterp->getAddressOfGlobal(GlobalDecl(VD))))
356 return addr;
357 auto evalStmt = VD->ensureEvaluatedStmt();
358 if (evalStmt && evalStmt->Value) {
359 if (const APValue* val = VD->evaluateValue()) {
360 if (VD->getType()->isIntegralType(C)) {
361 return reinterpret_cast<Longptr_t>(val->getInt().getRawData());
362 } else {
363 // The VD stores the init value; its lifetime should the lifetime of
364 // this offset.
365 switch (val->getKind()) {
366 case APValue::Int: {
367 if (val->getInt().isSigned())
368 fConstInitVal.fLong = (Longptr_t)val->getInt().getSExtValue();
369 else
370 fConstInitVal.fLong = (Longptr_t)val->getInt().getZExtValue();
371 return (Longptr_t) &fConstInitVal.fLong;
372 }
373 case APValue::Float:
374 if (&val->getFloat().getSemantics()
375 == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle()) {
376 fConstInitVal.fFloat = val->getFloat().convertToFloat();
377 return (Longptr_t)&fConstInitVal.fFloat;
378 } else if (&val->getFloat().getSemantics()
379 == (const llvm::fltSemantics*) &llvm::APFloat::IEEEdouble()) {
380 fConstInitVal.fDouble = val->getFloat().convertToDouble();
381 return (Longptr_t)&fConstInitVal.fDouble;
382 }
383 // else fall-through
384 default:
385 ;// fall-through
386 };
387 // fall-through
388 } // not integral type
389 } // have an APValue
390 } // have an initializing value
391 }
392 // FIXME: We have to explicitly check for not enum constant because the
393 // implementation of getAddressOfGlobal relies on mangling the name and in
394 // clang there is misbehaviour in MangleContext::shouldMangleDeclName.
395 // enum constants are essentially numbers and don't get addresses. However
396 // ROOT expects the address to the enum constant initializer to be returned.
397 else if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
398 // The raw data is stored as a long long, so we need to find the 'long'
399 // part.
400#ifdef R__BYTESWAP
401 // In this case at the beginning.
402 return reinterpret_cast<Longptr_t>(ECD->getInitVal().getRawData());
403#else
404 // In this case in the second part.
405 return reinterpret_cast<Longptr_t>(((char*)ECD->getInitVal().getRawData())+sizeof(Longptr_t) );
406#endif
407 return -1L;
408}
409
411{
412 if (!IsValid()) {
413 return 0L;
414 }
415 long property = 0L;
416
417 // If the declaration is public in a private nested struct, make the declaration
418 // private nonetheless, as for outside access (e.g. ROOT I/O) it's private:
419 // NOTE: this uses `GetDecl()`, to capture the access of the UsingShadowDecl,
420 // which is defined in the derived class and might differ from the access of the decl
421 // in the base class.
422 // TODO: move this somewhere such that TClingMethodInfo can use this, too.
423 const Decl *thisDecl = GetDecl();
424 clang::AccessSpecifier strictestAccess = thisDecl->getAccess();
425 const DeclContext *nonTransparentDC = thisDecl->getDeclContext();
426
427 auto getParentAccessAndNonTransparentDC = [&]() {
428 const Decl *declOrParent = thisDecl;
429 for (const auto *Parent = declOrParent->getDeclContext(); !llvm::isa<TranslationUnitDecl>(Parent);
430 Parent = declOrParent->getDeclContext()) {
431 if (!Parent->isTransparentContext()) {
432 if (const auto *RD = llvm::dyn_cast<clang::RecordDecl>(Parent)) {
433 if (!RD->isAnonymousStructOrUnion()) {
434 nonTransparentDC = RD;
435 break;
436 }
437 } else {
438 nonTransparentDC = Parent;
439 break;
440 }
441 }
442
443 declOrParent = llvm::dyn_cast<clang::Decl>(Parent);
444 if (!declOrParent)
445 break;
446 if (strictestAccess < declOrParent->getAccess()) {
447 strictestAccess = declOrParent->getAccess();
448 }
449 }
450 };
451
452 getParentAccessAndNonTransparentDC();
453
454 switch (strictestAccess) {
455 case clang::AS_public:
456 property |= kIsPublic;
457 break;
458 case clang::AS_protected:
459 property |= kIsProtected;
460 break;
461 case clang::AS_private:
462 property |= kIsPrivate;
463 break;
464 case clang::AS_none: //?
465 property |= kIsPublic;
466 break;
467 default:
468 // IMPOSSIBLE
469 break;
470 }
471 if (llvm::isa<clang::UsingShadowDecl>(thisDecl))
472 property |= kIsUsing;
473
474 const clang::ValueDecl *vd = GetTargetValueDecl();
475 if (const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(vd)) {
476 if (vard->isConstexpr())
477 property |= kIsConstexpr;
478 if (vard->getStorageClass() == clang::SC_Static) {
479 property |= kIsStatic;
480 } else if (nonTransparentDC->isNamespace()) {
481 // Data members of a namespace are global variable which were
482 // considered to be 'static' in the CINT (and thus ROOT) scheme.
483 property |= kIsStatic;
484 }
485 } else if (llvm::isa<clang::EnumConstantDecl>(vd)) {
486 // Enumeration constant are considered to be 'static' data member in
487 // the CINT (and thus ROOT) scheme.
488 property |= kIsStatic;
489 }
490 clang::QualType qt = vd->getType();
491 if (llvm::isa<clang::TypedefType>(qt)) {
492 property |= kIsTypedef;
493 }
494 qt = qt.getCanonicalType();
495 property = TClingDeclInfo::Property(property, qt);
496 const clang::TagType *tt = qt->getAs<clang::TagType>();
497 if (tt) {
498 // tt->getDecl() might deserialize.
499 cling::Interpreter::PushTransactionRAII RAII(fInterp);
500 const clang::TagDecl *td = tt->getDecl();
501 if (td->isClass()) {
502 property |= kIsClass;
503 }
504 else if (td->isStruct()) {
505 property |= kIsStruct;
506 }
507 else if (td->isUnion()) {
508 property |= kIsUnion;
509 }
510 else if (td->isEnum()) {
511 property |= kIsEnum;
512 }
513 }
514
515 if (const auto *RD = llvm::dyn_cast<RecordDecl>(thisDecl->getDeclContext())) {
516 if (RD->isUnion())
517 property |= kIsUnionMember;
518 }
519 // We can't be a namespace, can we?
520 // if (dc->isNamespace() && !dc->isTranslationUnit()) {
521 // property |= kIsNamespace;
522 // }
523 return property;
524}
525
527{
528 if (!IsValid()) {
529 return 0L;
530 }
531 const clang::ValueDecl *vd = GetTargetValueDecl();
532 clang::QualType qt = vd->getType();
533 return TClingTypeInfo(fInterp, qt).Property();
534}
535
537{
538 if (!IsValid()) {
539 return -1;
540 }
541
542 const clang::ValueDecl *vd = GetTargetValueDecl();
543 // Sanity check the current data member.
544 clang::Decl::Kind dk = vd->getKind();
545 if ((dk != clang::Decl::Field) && (dk != clang::Decl::Var) &&
546 (dk != clang::Decl::EnumConstant)) {
547 // Error, was not a data member, variable, or enumerator.
548 return -1;
549 }
550 clang::QualType qt = vd->getType();
551 if (qt->isIncompleteType()) {
552 // We cannot determine the size of forward-declared types.
553 return -1;
554 }
555 clang::ASTContext &context = GetDecl()->getASTContext();
556 // Truncate cast to fit to cint interface.
557 return static_cast<int>(context.getTypeSizeInChars(qt).getQuantity());
558}
559
561{
562 if (!IsValid()) {
563 return 0;
564 }
565
567 if (!fIoType.empty()) return fIoType.c_str();
568
569 // Note: This must be static because we return a pointer inside it!
570 static std::string buf;
571 buf.clear();
572 const clang::ValueDecl *vd = GetTargetValueDecl();
573 clang::QualType vdType = vd->getType();
574 // In CINT's version, the type name returns did *not* include any array
575 // information, ROOT's existing code depends on it.
576 while (vdType->isArrayType()) {
577 vdType = GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
578 }
579
580 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
582
584
585 return buf.c_str();
586}
587
589{
590 if (!IsValid()) {
591 return 0;
592 }
593
595 if (!fIoType.empty()) return fIoType.c_str();
596
597 // Note: This must be static because we return a pointer inside it!
598 static std::string buf;
599 buf.clear();
600 const clang::ValueDecl *vd = GetTargetValueDecl();
601 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
602 clang::QualType vdType = ROOT::TMetaUtils::ReSubstTemplateArg(vd->getType(), GetClassAsType());
603
604 ROOT::TMetaUtils::GetNormalizedName(buf, vdType, *fInterp, normCtxt);
605
606 // In CINT's version, the type name returns did *not* include any array
607 // information, ROOT's existing code depends on it.
608 // This might become part of the implementation of GetNormalizedName.
609 while (buf.length() && buf[buf.length()-1] == ']') {
610 size_t last = buf.rfind('['); // if this is not the bracket we are looking, the type is malformed.
611 if (last != std::string::npos) {
612 buf.erase(last);
613 }
614 }
615 return buf.c_str();
616}
617
618const char *TClingDataMemberInfo::Name() const
619{
620 if (!IsValid()) {
621 return 0;
622 }
623
625 if (!fIoName.empty()) return fIoName.c_str();
626
627 return TClingDeclInfo::Name();
628}
629
631{
632 if (!IsValid()) {
633 return 0;
634 }
635
636 //NOTE: We can't use it as a cache due to the "thoughtful" self iterator
637 //if (fTitle.size())
638 // return fTitle.c_str();
639
640 bool titleFound=false;
641 // Try to get the comment either from the annotation or the header file if present
642 std::string attribute_s;
643 const Decl* decl = GetTargetValueDecl();
644 for (Decl::attr_iterator attrIt = decl->attr_begin();
645 attrIt!=decl->attr_end() && !titleFound ;++attrIt){
646 if (0 == ROOT::TMetaUtils::extractAttrString(*attrIt, attribute_s) &&
647 attribute_s.find(ROOT::TMetaUtils::propNames::separator) == std::string::npos){
648 fTitle = attribute_s;
649 titleFound=true;
650 }
651 }
652
653 if (!titleFound && !decl->isFromASTFile()) {
654 // Try to get the comment from the header file if present
655 // but not for decls from AST file, where rootcling would have
656 // created an annotation
658 }
659
660 return fTitle.c_str();
661}
662
663// ValidArrayIndex return a static string (so use it or copy it immediately, do not
664// call GrabIndex twice in the same expression) containing the size of the
665// array data member.
667{
668 if (!IsValid()) {
669 return llvm::StringRef();
670 }
671 const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(GetTargetValueDecl());
672 if (FD)
674 return {};
675}
676
long Longptr_t
Definition: RtypesCore.h:82
@ kIsPublic
Definition: TDictionary.h:75
@ kIsUnionMember
Definition: TDictionary.h:74
@ kIsConstexpr
Definition: TDictionary.h:93
@ kIsClass
Definition: TDictionary.h:65
@ kIsEnum
Definition: TDictionary.h:68
@ kIsPrivate
Definition: TDictionary.h:77
@ kIsUsing
Definition: TDictionary.h:97
@ kIsStatic
Definition: TDictionary.h:80
@ kIsStruct
Definition: TDictionary.h:66
@ kIsProtected
Definition: TDictionary.h:76
@ kIsUnion
Definition: TDictionary.h:67
@ kIsTypedef
Definition: TDictionary.h:69
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
Definition: TInterpreter.h:46
#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
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
TClingDataMemberIter fIter
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.
long Property() const
static bool WantsRegularMembers(EMemberSelection sel)
Definition: TDictionary.h:220
EMemberSelection
Kinds of members to include in lists.
Definition: TDictionary.h:215
static bool WantsUsingDecls(EMemberSelection sel)
Definition: TDictionary.h:221
const void * DeclId_t
Definition: TDictionary.h:223
RooCmdArg Layout(double xmin, double xmax=0.99, double ymin=0.95)
Type
enumeration specifying the integration types.
double Var(const RVec< T > &v)
Get the variance of the elements of an RVec.
Definition: RVec.hxx:1997
void(off) SmallVectorTemplateBase< T
static double C[]
static const std::string separator("@@@")
int extractAttrString(clang::Attr *attribute, std::string &attrString)
Extract attr string.
void GetNormalizedName(std::string &norm_name, const clang::QualType &type, const cling::Interpreter &interpreter, const TNormalizedCtxt &normCtxt)
Return the type name normalized for ROOT, keeping only the ROOT opaque typedef (Double32_t,...
clang::QualType ReSubstTemplateArg(clang::QualType input, const clang::Type *instance)
Check if 'input' or any of its template parameter was substituted when instantiating the class templa...
void GetFullyQualifiedTypeName(std::string &name, const clang::QualType &type, const cling::Interpreter &interpreter)
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propName<separator>propValue" format.
llvm::StringRef DataMemberInfo__ValidArrayIndex(const cling::Interpreter &interp, const clang::DeclaratorDecl &m, int *errnum=nullptr, llvm::StringRef *errstr=nullptr)
ValidArrayIndex return a static string (so use it or copy it immediatly, do not call GrabIndex twice ...
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=0)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
static constexpr double L
Definition: TString.h:850
const char * Float
const char * Int
const char * cnt
Definition: TXMLSetup.cxx:75
auto * tt
Definition: textangle.C:16