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 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
union TClingDataMemberInfo::@28 fConstInitVal
const clang::UsingShadowDecl * GetAsUsingShadowDecl() 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
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)
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