Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
190const clang::Type *TClingDataMemberInfo::GetClassAsType() const {
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 // We can't reassign constexpr or const variables. We can compute the
356 // initializer.
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());
361 } else {
362 // The VD stores the init value; its lifetime should the lifetime of
363 // this offset.
364 switch (val->getKind()) {
365 case APValue::Int: {
366 if (val->getInt().isSigned())
367 fConstInitVal.fLong = (Longptr_t)val->getInt().getSExtValue();
368 else
369 fConstInitVal.fLong = (Longptr_t)val->getInt().getZExtValue();
370 return (Longptr_t) &fConstInitVal.fLong;
371 }
372 case APValue::Float:
373 if (&val->getFloat().getSemantics()
374 == (const llvm::fltSemantics*)&llvm::APFloat::IEEEsingle()) {
375 fConstInitVal.fFloat = val->getFloat().convertToFloat();
376 return (Longptr_t)&fConstInitVal.fFloat;
377 } else if (&val->getFloat().getSemantics()
378 == (const llvm::fltSemantics*) &llvm::APFloat::IEEEdouble()) {
379 fConstInitVal.fDouble = val->getFloat().convertToDouble();
380 return (Longptr_t)&fConstInitVal.fDouble;
381 }
382 // else fall-through
383 default:
384 ;// fall-through
385 };
386 // fall-through
387 } // not integral type
388 } // have an APValue
389 } // have an initializing value
390
391 // Try the slow operation.
392 if (Longptr_t addr = reinterpret_cast<Longptr_t>(fInterp->getAddressOfGlobal(GlobalDecl(VD))))
393 return addr;
394 }
395 // FIXME: We have to explicitly check for not enum constant because the
396 // implementation of getAddressOfGlobal relies on mangling the name and in
397 // clang there is misbehaviour in MangleContext::shouldMangleDeclName.
398 // enum constants are essentially numbers and don't get addresses. However
399 // ROOT expects the address to the enum constant initializer to be returned.
400 else if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
401 // The raw data is stored as a long long, so we need to find the 'long'
402 // part.
403#ifdef R__BYTESWAP
404 // In this case at the beginning.
405 return reinterpret_cast<Longptr_t>(ECD->getInitVal().getRawData());
406#else
407 // In this case in the second part.
408 return reinterpret_cast<Longptr_t>(((char*)ECD->getInitVal().getRawData())+sizeof(Longptr_t) );
409#endif
410 return -1L;
411}
412
414{
415 if (!IsValid()) {
416 return 0L;
417 }
418 long property = 0L;
419
420 // If the declaration is public in a private nested struct, make the declaration
421 // private nonetheless, as for outside access (e.g. ROOT I/O) it's private:
422 // NOTE: this uses `GetDecl()`, to capture the access of the UsingShadowDecl,
423 // which is defined in the derived class and might differ from the access of the decl
424 // in the base class.
425 // TODO: move this somewhere such that TClingMethodInfo can use this, too.
426 const Decl *thisDecl = GetDecl();
427 clang::AccessSpecifier strictestAccess = thisDecl->getAccess();
428 const DeclContext *nonTransparentDC = thisDecl->getDeclContext();
429
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;
438 break;
439 }
440 } else {
441 nonTransparentDC = Parent;
442 break;
443 }
444 }
445
446 declOrParent = llvm::dyn_cast<clang::Decl>(Parent);
447 if (!declOrParent)
448 break;
449 if (strictestAccess < declOrParent->getAccess()) {
450 strictestAccess = declOrParent->getAccess();
451 }
452 }
453 };
454
455 getParentAccessAndNonTransparentDC();
456 // TODO: Now that we have the kIsNotReacheable we could return the property
457 // to be reflecting the local information. However it is unclear if the
458 // information is used as-is (it appears to not be used in ROOT proper)
459 switch (strictestAccess) {
460 case clang::AS_public:
461 property |= kIsPublic;
462 break;
463 case clang::AS_protected:
464 property |= kIsProtected | kIsNotReacheable;
465 break;
466 case clang::AS_private:
467 property |= kIsPrivate | kIsNotReacheable;
468 break;
469 case clang::AS_none: //?
470 property |= kIsPublic;
471 break;
472 default:
473 // IMPOSSIBLE
474 assert(false && "Unexpected value for the access property value in Clang");
475 break;
476 }
477 if (llvm::isa<clang::UsingShadowDecl>(thisDecl))
478 property |= kIsUsing;
479
480 const clang::ValueDecl *vd = GetTargetValueDecl();
481 if (const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(vd)) {
482 if (vard->isConstexpr())
483 property |= kIsConstexpr;
484 if (vard->getStorageClass() == clang::SC_Static) {
485 property |= kIsStatic;
486 } else if (nonTransparentDC->isNamespace()) {
487 // Data members of a namespace are global variable which were
488 // considered to be 'static' in the CINT (and thus ROOT) scheme.
489 property |= kIsStatic;
490 }
491 } else if (llvm::isa<clang::EnumConstantDecl>(vd)) {
492 // Enumeration constant are considered to be 'static' data member in
493 // the CINT (and thus ROOT) scheme.
494 property |= kIsStatic;
495 }
496 clang::QualType qt = vd->getType();
497 if (llvm::isa<clang::TypedefType>(qt)) {
498 property |= kIsTypedef;
499 }
500 qt = qt.getCanonicalType();
501 property = TClingDeclInfo::Property(property, qt);
502 const clang::TagType *tt = qt->getAs<clang::TagType>();
503 if (tt) {
504 // tt->getDecl() might deserialize.
505 cling::Interpreter::PushTransactionRAII RAII(fInterp);
506 const clang::TagDecl *td = tt->getDecl();
507 if (td->isClass()) {
508 property |= kIsClass;
509 }
510 else if (td->isStruct()) {
511 property |= kIsStruct;
512 }
513 else if (td->isUnion()) {
514 property |= kIsUnion;
515 }
516 else if (td->isEnum()) {
517 property |= kIsEnum;
518 }
519 }
520
521 if (const auto *RD = llvm::dyn_cast<RecordDecl>(thisDecl->getDeclContext())) {
522 if (RD->isUnion())
523 property |= kIsUnionMember;
524 }
525 // We can't be a namespace, can we?
526 // if (dc->isNamespace() && !dc->isTranslationUnit()) {
527 // property |= kIsNamespace;
528 // }
529 return property;
530}
531
533{
534 if (!IsValid()) {
535 return 0L;
536 }
537 const clang::ValueDecl *vd = GetTargetValueDecl();
538 clang::QualType qt = vd->getType();
539 return TClingTypeInfo(fInterp, qt).Property();
540}
541
543{
544 if (!IsValid()) {
545 return -1;
546 }
547
548 const clang::ValueDecl *vd = GetTargetValueDecl();
549 // Sanity check the current data member.
550 clang::Decl::Kind dk = vd->getKind();
551 if ((dk != clang::Decl::Field) && (dk != clang::Decl::Var) &&
552 (dk != clang::Decl::EnumConstant)) {
553 // Error, was not a data member, variable, or enumerator.
554 return -1;
555 }
556 clang::QualType qt = vd->getType();
557 if (qt->isIncompleteType()) {
558 // We cannot determine the size of forward-declared types.
559 return -1;
560 }
561 clang::ASTContext &context = GetDecl()->getASTContext();
562 // Truncate cast to fit to cint interface.
563 return static_cast<int>(context.getTypeSizeInChars(qt).getQuantity());
564}
565
567{
568 if (!IsValid()) {
569 return nullptr;
570 }
571
573 if (!fIoType.empty()) return fIoType.c_str();
574
575 // Note: This must be static because we return a pointer inside it!
576 static std::string buf;
577 buf.clear();
578 const clang::ValueDecl *vd = GetTargetValueDecl();
579 clang::QualType vdType = vd->getType();
580 // In CINT's version, the type name returns did *not* include any array
581 // information, ROOT's existing code depends on it.
582 while (vdType->isArrayType()) {
583 vdType = GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
584 }
585
586 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
588
590
591 return buf.c_str();
592}
593
595{
596 if (!IsValid()) {
597 return nullptr;
598 }
599
601 if (!fIoType.empty()) return fIoType.c_str();
602
603 // Note: This must be static because we return a pointer inside it!
604 static std::string buf;
605 buf.clear();
606 const clang::ValueDecl *vd = GetTargetValueDecl();
607 // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
608 clang::QualType vdType = ROOT::TMetaUtils::ReSubstTemplateArg(vd->getType(), GetClassAsType());
609
610 ROOT::TMetaUtils::GetNormalizedName(buf, vdType, *fInterp, normCtxt);
611
612 // In CINT's version, the type name returns did *not* include any array
613 // information, ROOT's existing code depends on it.
614 // This might become part of the implementation of GetNormalizedName.
615 while (buf.length() && buf[buf.length()-1] == ']') {
616 size_t last = buf.rfind('['); // if this is not the bracket we are looking, the type is malformed.
617 if (last != std::string::npos) {
618 buf.erase(last);
619 }
620 }
621 return buf.c_str();
622}
623
624const char *TClingDataMemberInfo::Name() const
625{
626 if (!IsValid()) {
627 return nullptr;
628 }
629
631 if (!fIoName.empty()) return fIoName.c_str();
632
633 return TClingDeclInfo::Name();
634}
635
637{
638 if (!IsValid()) {
639 return nullptr;
640 }
641
642 //NOTE: We can't use it as a cache due to the "thoughtful" self iterator
643 //if (fTitle.size())
644 // return fTitle.c_str();
645
646 bool titleFound=false;
647 // Try to get the comment either from the annotation or the header file if present
648 std::string attribute_s;
649 const Decl* decl = GetTargetValueDecl();
650 for (Decl::attr_iterator attrIt = decl->attr_begin();
651 attrIt!=decl->attr_end() && !titleFound ;++attrIt){
652 if (0 == ROOT::TMetaUtils::extractAttrString(*attrIt, attribute_s) &&
653 attribute_s.find(ROOT::TMetaUtils::propNames::separator) == std::string::npos){
654 fTitle = attribute_s;
655 titleFound=true;
656 }
657 }
658
659 if (!titleFound && !decl->isFromASTFile()) {
660 // Try to get the comment from the header file if present
661 // but not for decls from AST file, where rootcling would have
662 // created an annotation
664 }
665
666 return fTitle.c_str();
667}
668
669// ValidArrayIndex return a static string (so use it or copy it immediately, do not
670// call GrabIndex twice in the same expression) containing the size of the
671// array data member.
673{
674 if (!IsValid()) {
675 return llvm::StringRef();
676 }
677 const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(GetTargetValueDecl());
678 if (FD)
680 return {};
681}
682
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
@ kIsNotReacheable
Definition TDictionary.h:87
@ 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
#define R__LOCKGUARD(mutex)
Emulation of the CINT ClassInfo class.
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
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
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
TClingDeclInfo()=default
virtual const clang::Decl * GetDecl() const
Emulation of the CINT TypeInfo class.
long Property() const
static bool WantsRegularMembers(EMemberSelection sel)
EMemberSelection
Kinds of members to include in lists.
static bool WantsUsingDecls(EMemberSelection sel)
const void * DeclId_t
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)
llvm::StringRef GetComment(const clang::Decl &decl, clang::SourceLocation *loc=nullptr)
Returns the comment (// striped away), annotating declaration in a meaningful for ROOT IO way.
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 ...
auto * tt
Definition textangle.C:16