ROOT  6.06/09
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 
14 Emulation of the CINT DataMemberInfo class.
15 
16 The CINT C++ interpreter provides an interface to metadata about
17 the data members of a class through the DataMemberInfo class. This
18 class provides the same functionality, using an interface as close
19 as possible to DataMemberInfo but the data member metadata comes
20 from the Clang C++ compiler, not CINT.
21 */
22 
23 #include "TClingDataMemberInfo.h"
24 
25 #include "TDictionary.h"
26 #include "TClingTypeInfo.h"
27 #include "TMetaUtils.h"
28 #include "TClassEdit.h"
29 #include "TError.h"
30 
31 #include "clang/AST/Attr.h"
32 #include "clang/AST/ASTContext.h"
33 #include "clang/AST/Decl.h"
34 #include "clang/AST/GlobalDecl.h"
35 #include "clang/AST/Expr.h"
36 #include "clang/AST/ExprCXX.h"
37 #include "clang/AST/PrettyPrinter.h"
38 #include "clang/AST/RecordLayout.h"
39 #include "clang/AST/Type.h"
40 
41 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/raw_ostream.h"
43 #include "llvm/ADT/APSInt.h"
44 #include "llvm/ADT/APFloat.h"
45 
46 using namespace clang;
47 
48 TClingDataMemberInfo::TClingDataMemberInfo(cling::Interpreter *interp,
49  TClingClassInfo *ci)
50 : fInterp(interp), fClassInfo(0), fFirstTime(true), fTitle(""), fSingleDecl(0), fContextIdx(0U), fIoType(""), fIoName("")
51 {
52  if (!ci) {
53  // We are meant to iterate over the global namespace (well at least CINT did).
54  fClassInfo = new TClingClassInfo(interp);
55  } else {
56  fClassInfo = new TClingClassInfo(*ci);
57  }
58  if (fClassInfo->IsValid()) {
59  Decl *D = const_cast<Decl*>(fClassInfo->GetDecl());
60 
61  clang::DeclContext *dc = llvm::cast<clang::DeclContext>(D);
62  dc->collectAllContexts(fContexts);
63 
64  // Could trigger deserialization of decls.
65  cling::Interpreter::PushTransactionRAII RAII(interp);
66  fIter = llvm::cast<clang::DeclContext>(D)->decls_begin();
67  const TagDecl *TD = ROOT::TMetaUtils::GetAnnotatedRedeclarable(llvm::dyn_cast<TagDecl>(D));
68  if (TD)
69  fIter = TD->decls_begin();
70 
71  // Move to first data member.
72  InternalNext();
73  fFirstTime = true;
74  }
75 
76 }
77 
78 TClingDataMemberInfo::TClingDataMemberInfo(cling::Interpreter *interp,
79  const clang::ValueDecl *ValD,
80  TClingClassInfo *ci)
81 : fInterp(interp), fClassInfo(ci ? new TClingClassInfo(*ci) : new TClingClassInfo(interp)), fFirstTime(true),
82  fTitle(""), fSingleDecl(ValD), fContextIdx(0U), fIoType(""), fIoName(""){
83 
84  using namespace llvm;
85  assert((ci || isa<TranslationUnitDecl>(ValD->getDeclContext()) ||
86  (ValD->getDeclContext()->isTransparentContext() && isa<TranslationUnitDecl>(ValD->getDeclContext()->getParent()) ) ||
87  isa<EnumConstantDecl>(ValD)) && "Not TU?");
88  assert((isa<VarDecl>(ValD) ||
89  isa<FieldDecl>(ValD) ||
90  isa<EnumConstantDecl>(ValD) ||
91  isa<IndirectFieldDecl>(ValD)) &&
92  "The decl should be either VarDecl or FieldDecl or EnumConstDecl");
93 
94 }
95 
97 {
98  // Three cases:
99  // 1) 00: none to be checked
100  // 2) 01: type to be checked
101  // 3) 10: none to be checked
102  // 4) 11: both to be checked
103  unsigned int code = fIoType.empty() + (int(fIoName.empty()) << 1);
104 
105  if (code == 0) return;
106 
107  const Decl* decl = GetDecl();
108 
109  if (code == 3 || code == 2) ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"ioname",fIoName);
110  if (code == 3 || code == 1) ROOT::TMetaUtils::ExtractAttrPropertyFromName(*decl,"iotype",fIoType);
111 
112 }
113 
115 {
116  if (!IsValid()) {
117  return TDictionary::DeclId_t();
118  }
119  return (const clang::Decl*)(GetDecl()->getCanonicalDecl());
120 }
121 
123 {
124  if (!IsValid()) {
125  return -1;
126  }
127  // Sanity check the current data member.
128  clang::Decl::Kind DK = GetDecl()->getKind();
129  if (
130  (DK != clang::Decl::Field) &&
131  (DK != clang::Decl::Var) &&
132  (DK != clang::Decl::EnumConstant)
133  ) {
134  // Error, was not a data member, variable, or enumerator.
135  return -1;
136  }
137  if (DK == clang::Decl::EnumConstant) {
138  // We know that an enumerator value does not have array type.
139  return 0;
140  }
141  // To get this information we must count the number
142  // of array type nodes in the canonical type chain.
143  const clang::ValueDecl *VD = llvm::dyn_cast<clang::ValueDecl>(GetDecl());
144  clang::QualType QT = VD->getType().getCanonicalType();
145  int cnt = 0;
146  while (1) {
147  if (QT->isArrayType()) {
148  ++cnt;
149  QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
150  continue;
151  }
152  else if (QT->isReferenceType()) {
153  QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
154  continue;
155  }
156  else if (QT->isPointerType()) {
157  QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
158  continue;
159  }
160  else if (QT->isMemberPointerType()) {
161  QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
162  continue;
163  }
164  break;
165  }
166  return cnt;
167 }
168 
170 {
171  if (!IsValid()) {
172  return -1;
173  }
174  // Sanity check the current data member.
175  clang::Decl::Kind DK = GetDecl()->getKind();
176  if (
177  (DK != clang::Decl::Field) &&
178  (DK != clang::Decl::Var) &&
179  (DK != clang::Decl::EnumConstant)
180  ) {
181  // Error, was not a data member, variable, or enumerator.
182  return -1;
183  }
184  if (DK == clang::Decl::EnumConstant) {
185  // We know that an enumerator value does not have array type.
186  return 0;
187  }
188  // To get this information we must count the number
189  // of array type nodes in the canonical type chain.
190  const clang::ValueDecl *VD = llvm::dyn_cast<clang::ValueDecl>(GetDecl());
191  clang::QualType QT = VD->getType().getCanonicalType();
192  int paran = ArrayDim();
193  if ((dim < 0) || (dim >= paran)) {
194  // Passed dimension is out of bounds.
195  return -1;
196  }
197  int cnt = dim;
198  int max = 0;
199  while (1) {
200  if (QT->isArrayType()) {
201  if (cnt == 0) {
202  if (const clang::ConstantArrayType *CAT =
203  llvm::dyn_cast<clang::ConstantArrayType>(QT)
204  ) {
205  max = static_cast<int>(CAT->getSize().getZExtValue());
206  }
207  else if (llvm::dyn_cast<clang::IncompleteArrayType>(QT)) {
208  max = INT_MAX;
209  }
210  else {
211  max = -1;
212  }
213  break;
214  }
215  --cnt;
216  QT = llvm::cast<clang::ArrayType>(QT)->getElementType();
217  continue;
218  }
219  else if (QT->isReferenceType()) {
220  QT = llvm::cast<clang::ReferenceType>(QT)->getPointeeType();
221  continue;
222  }
223  else if (QT->isPointerType()) {
224  QT = llvm::cast<clang::PointerType>(QT)->getPointeeType();
225  continue;
226  }
227  else if (QT->isMemberPointerType()) {
228  QT = llvm::cast<clang::MemberPointerType>(QT)->getPointeeType();
229  continue;
230  }
231  break;
232  }
233  return max;
234 }
235 
237 {
238  assert(!fSingleDecl && "This is not an iterator!");
239 
240  bool increment = true;
241  // Move to next acceptable data member.
242  while (fFirstTime || *fIter) {
243  // Move to next decl in context.
244  if (fFirstTime) {
245  fFirstTime = false;
246  }
247  else if (increment) {
248  ++fIter;
249  } else {
250  increment = true;
251  }
252 
253  // Handle reaching end of current decl context.
254  if (!*fIter) {
255  if (fIterStack.size()) {
256  // End of current decl context, and we have more to go.
257  fIter = fIterStack.back();
258  fIterStack.pop_back();
259  continue;
260  }
261  while (!*fIter) {
262  // Check the next decl context (of namespace)
263  ++fContextIdx;
264  if (fContextIdx >= fContexts.size()) {
265  // Iterator is now invalid.
266  return 0;
267  }
268  clang::DeclContext *dc = fContexts[fContextIdx];
269  // Could trigger deserialization of decls.
270  cling::Interpreter::PushTransactionRAII RAII(fInterp);
271  fIter = dc->decls_begin();
272  if (*fIter) {
273  // Good, a non-empty context.
274  break;
275  }
276  }
277  }
278 
279  // Valid decl, recurse into it, accept it, or reject it.
280  clang::Decl::Kind DK = fIter->getKind();
281  if (DK == clang::Decl::Enum) {
282  // We have an enum, recurse into these.
283  // Note: For C++11 we will have to check for a transparent context.
284  fIterStack.push_back(fIter);
285  fIter = llvm::dyn_cast<clang::DeclContext>(*fIter)->decls_begin();
286  increment = false; // avoid the next incrementation
287  continue;
288  }
289  if ((DK == clang::Decl::Field) || (DK == clang::Decl::EnumConstant) ||
290  (DK == clang::Decl::Var)) {
291  // Stop on class data members, enumerator values,
292  // and namespace variable members.
293  return 1;
294  }
295  }
296  return 0;
297 }
298 
300 {
301  using namespace clang;
302 
303  if (!IsValid()) {
304  return -1L;
305  }
306 
307  const Decl *D = GetDecl();
308  ASTContext& C = D->getASTContext();
309  if (const FieldDecl *FldD = dyn_cast<FieldDecl>(D)) {
310  // The current member is a non-static data member.
311  clang::ASTContext &Context = FldD->getASTContext();
312  const clang::RecordDecl *RD = FldD->getParent();
313  const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
314  uint64_t bits = Layout.getFieldOffset(FldD->getFieldIndex());
315  int64_t offset = Context.toCharUnitsFromBits(bits).getQuantity();
316  return static_cast<long>(offset);
317  }
318  else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
319  // Could trigger deserialization of decls, in particular in case
320  // of constexpr, like:
321  // static constexpr Long64_t something = std::numeric_limits<Long64_t>::max();
322  cling::Interpreter::PushTransactionRAII RAII(fInterp);
323 
324  if (VD->hasInit() && VD->checkInitIsICE()) {
325  // FIXME: We might want in future to printout the reason why the eval
326  // failed.
327  const APValue* val = VD->evaluateValue();
328  if (VD->getType()->isIntegralType(C)) {
329  return reinterpret_cast<long>(val->getInt().getRawData());
330  } else {
331  // The VD stores the init value; its lifetime should the lifetime of
332  // this offset.
333  switch (val->getKind()) {
334  case APValue::Int: {
335  if (val->getInt().isSigned())
336  fConstInitVal.fLong = (long)val->getInt().getSExtValue();
337  else
338  fConstInitVal.fLong = (long)val->getInt().getZExtValue();
339  return (long) &fConstInitVal.fLong;
340  }
341  case APValue::Float:
342  if (&val->getFloat().getSemantics()
343  == &llvm::APFloat::IEEEsingle) {
344  fConstInitVal.fFloat = val->getFloat().convertToFloat();
345  return (long)&fConstInitVal.fFloat;
346  } else if (&val->getFloat().getSemantics()
347  == &llvm::APFloat::IEEEdouble) {
348  fConstInitVal.fDouble = val->getFloat().convertToDouble();
349  return (long)&fConstInitVal.fDouble;
350  }
351  // else fall-through
352  default:
353  ;// fall-through
354  };
355  // fall-through
356  }
357  }
358  return reinterpret_cast<long>(fInterp->getAddressOfGlobal(GlobalDecl(VD)));
359  }
360  // FIXME: We have to explicitly check for not enum constant because the
361  // implementation of getAddressOfGlobal relies on mangling the name and in
362  // clang there is misbehaviour in MangleContext::shouldMangleDeclName.
363  // enum constants are essentially numbers and don't get addresses. However
364  // ROOT expects the address to the enum constant initializer to be returned.
365  else if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
366  // The raw data is stored as a long long, so we need to find the 'long'
367  // part.
368 #ifdef R__BYTESWAP
369  // In this case at the beginning.
370  return reinterpret_cast<long>(ECD->getInitVal().getRawData());
371 #else
372  // In this case in the second part.
373  return reinterpret_cast<long>(((char*)ECD->getInitVal().getRawData())+sizeof(long) );
374 #endif
375  return -1L;
376 }
377 
379 {
380  if (!IsValid()) {
381  return 0L;
382  }
383  long property = 0L;
384  const clang::Decl *declaccess = GetDecl();
385  if (declaccess->getDeclContext()->isTransparentContext()) {
386  declaccess = llvm::dyn_cast<clang::Decl>(declaccess->getDeclContext());
387  if (!declaccess) declaccess = GetDecl();
388  }
389  switch (declaccess->getAccess()) {
390  case clang::AS_public:
391  property |= kIsPublic;
392  break;
393  case clang::AS_protected:
394  property |= kIsProtected;
395  break;
396  case clang::AS_private:
397  property |= kIsPrivate;
398  break;
399  case clang::AS_none:
400  if (declaccess->getDeclContext()->isNamespace()) {
401  property |= kIsPublic;
402  } else {
403  // IMPOSSIBLE
404  }
405  break;
406  default:
407  // IMPOSSIBLE
408  break;
409  }
410  if (const clang::VarDecl *vard = llvm::dyn_cast<clang::VarDecl>(GetDecl())) {
411  if (vard->getStorageClass() == clang::SC_Static) {
412  property |= kIsStatic;
413  } else if (declaccess->getDeclContext()->isNamespace()) {
414  // Data members of a namespace are global variable which were
415  // considered to be 'static' in the CINT (and thus ROOT) scheme.
416  property |= kIsStatic;
417  }
418  }
419  if (llvm::isa<clang::EnumConstantDecl>(GetDecl())) {
420  // Enumeration constant are considered to be 'static' data member in
421  // the CINT (and thus ROOT) scheme.
422  property |= kIsStatic;
423  }
424  const clang::ValueDecl *vd = llvm::dyn_cast<clang::ValueDecl>(GetDecl());
425  clang::QualType qt = vd->getType();
426  if (llvm::isa<clang::TypedefType>(qt)) {
427  property |= kIsTypedef;
428  }
429  qt = qt.getCanonicalType();
430  if (qt.isConstQualified()) {
431  property |= kIsConstant;
432  }
433  while (1) {
434  if (qt->isArrayType()) {
435  property |= kIsArray;
436  qt = llvm::cast<clang::ArrayType>(qt)->getElementType();
437  continue;
438  }
439  else if (qt->isReferenceType()) {
440  property |= kIsReference;
441  qt = llvm::cast<clang::ReferenceType>(qt)->getPointeeType();
442  continue;
443  }
444  else if (qt->isPointerType()) {
445  property |= kIsPointer;
446  if (qt.isConstQualified()) {
447  property |= kIsConstPointer;
448  }
449  qt = llvm::cast<clang::PointerType>(qt)->getPointeeType();
450  continue;
451  }
452  else if (qt->isMemberPointerType()) {
453  qt = llvm::cast<clang::MemberPointerType>(qt)->getPointeeType();
454  continue;
455  }
456  break;
457  }
458  if (qt->isBuiltinType()) {
459  property |= kIsFundamental;
460  }
461  if (qt.isConstQualified()) {
462  property |= kIsConstant;
463  }
464  const clang::TagType *tt = qt->getAs<clang::TagType>();
465  if (tt) {
466  const clang::TagDecl *td = tt->getDecl();
467  if (td->isClass()) {
468  property |= kIsClass;
469  }
470  else if (td->isStruct()) {
471  property |= kIsStruct;
472  }
473  else if (td->isUnion()) {
474  property |= kIsUnion;
475  }
476  else if (td->isEnum()) {
477  property |= kIsEnum;
478  }
479  }
480  // We can't be a namespace, can we?
481  // if (dc->isNamespace() && !dc->isTranslationUnit()) {
482  // property |= kIsNamespace;
483  // }
484  return property;
485 }
486 
488 {
489  if (!IsValid()) {
490  return 0L;
491  }
492  const clang::ValueDecl *vd = llvm::dyn_cast<clang::ValueDecl>(GetDecl());
493  clang::QualType qt = vd->getType();
494  return TClingTypeInfo(fInterp, qt).Property();
495 }
496 
498 {
499  if (!IsValid()) {
500  return -1;
501  }
502 
503  // Sanity check the current data member.
504  clang::Decl::Kind dk = GetDecl()->getKind();
505  if ((dk != clang::Decl::Field) && (dk != clang::Decl::Var) &&
506  (dk != clang::Decl::EnumConstant)) {
507  // Error, was not a data member, variable, or enumerator.
508  return -1;
509  }
510  const clang::ValueDecl *vd = llvm::dyn_cast<clang::ValueDecl>(GetDecl());
511  clang::QualType qt = vd->getType();
512  if (qt->isIncompleteType()) {
513  // We cannot determine the size of forward-declared types.
514  return -1;
515  }
516  clang::ASTContext &context = GetDecl()->getASTContext();
517  // Truncate cast to fit to cint interface.
518  return static_cast<int>(context.getTypeSizeInChars(qt).getQuantity());
519 }
520 
522 {
523  if (!IsValid()) {
524  return 0;
525  }
526 
528  if (!fIoType.empty()) return fIoType.c_str();
529 
530  // Note: This must be static because we return a pointer inside it!
531  static std::string buf;
532  buf.clear();
533  if (const clang::ValueDecl *vd = llvm::dyn_cast<clang::ValueDecl>(GetDecl())) {
534  clang::QualType vdType = vd->getType();
535  // In CINT's version, the type name returns did *not* include any array
536  // information, ROOT's existing code depends on it.
537  while (vdType->isArrayType()) {
538  vdType = GetDecl()->getASTContext().getQualifiedType(vdType->getBaseElementTypeUnsafe(),vdType.getQualifiers());
539  }
540 
541  // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
543 
545 
546  return buf.c_str();
547  }
548  return 0;
549 }
550 
552 {
553  if (!IsValid()) {
554  return 0;
555  }
556 
558  if (!fIoType.empty()) return fIoType.c_str();
559 
560  // Note: This must be static because we return a pointer inside it!
561  static std::string buf;
562  buf.clear();
563  if (const clang::ValueDecl *vd = llvm::dyn_cast<clang::ValueDecl>(GetDecl())) {
564  // if (we_need_to_do_the_subst_because_the_class_is_a_template_instance_of_double32_t)
565  clang::QualType vdType = ROOT::TMetaUtils::ReSubstTemplateArg(vd->getType(), fClassInfo->GetType());
566 
567  ROOT::TMetaUtils::GetNormalizedName(buf, vdType, *fInterp, normCtxt);
568 
569  // In CINT's version, the type name returns did *not* include any array
570  // information, ROOT's existing code depends on it.
571  // This might become part of the implementation of GetNormalizedName.
572  while (buf.length() && buf[buf.length()-1] == ']') {
573  size_t last = buf.rfind('['); // if this is not the bracket we are looking, the type is malformed.
574  if (last != std::string::npos) {
575  buf.erase(last);
576  }
577  }
578  return buf.c_str();
579  }
580  return 0;
581 }
582 
583 const char *TClingDataMemberInfo::Name() const
584 {
585  if (!IsValid()) {
586  return 0;
587  }
588 
590  if (!fIoName.empty()) return fIoName.c_str();
591 
592  // Note: This must be static because we return a pointer inside it!
593  static std::string buf;
594  buf.clear();
595 
596  if (const clang::NamedDecl *nd = llvm::dyn_cast<clang::NamedDecl>(GetDecl())) {
597  clang::PrintingPolicy policy(GetDecl()->getASTContext().getPrintingPolicy());
598  llvm::raw_string_ostream stream(buf);
599  nd->getNameForDiagnostic(stream, policy, /*Qualified=*/false);
600  stream.flush();
601  return buf.c_str();
602  }
603  return 0;
604 }
605 
607 {
608  if (!IsValid()) {
609  return 0;
610  }
611 
612  //NOTE: We can't use it as a cache due to the "thoughtful" self iterator
613  //if (fTitle.size())
614  // return fTitle.c_str();
615 
616  bool titleFound=false;
617  // Try to get the comment either from the annotation or the header file if present
618  std::string attribute_s;
619  const Decl* decl = GetDecl();
620  for (Decl::attr_iterator attrIt = decl->attr_begin();
621  attrIt!=decl->attr_end() && !titleFound ;++attrIt){
622  if (0 == ROOT::TMetaUtils::extractAttrString(*attrIt, attribute_s) &&
623  attribute_s.find(ROOT::TMetaUtils::propNames::separator) == std::string::npos){
624  fTitle = attribute_s;
625  titleFound=true;
626  }
627  }
628 
629  if (!titleFound && !GetDecl()->isFromASTFile()) {
630  // Try to get the comment from the header file if present
631  // but not for decls from AST file, where rootcling would have
632  // created an annotation
634  }
635 
636  return fTitle.c_str();
637 }
638 
639 // ValidArrayIndex return a static string (so use it or copy it immediately, do not
640 // call GrabIndex twice in the same expression) containing the size of the
641 // array data member.
643 {
644  if (!IsValid()) {
645  return llvm::StringRef();
646  }
647  const clang::DeclaratorDecl *FD = llvm::dyn_cast<clang::DeclaratorDecl>(GetDecl());
649  else return llvm::StringRef();
650 }
651 
const char * Name() const
Definition: TString.h:780
bool IsValid() const
const char * Int
RooArgList L(const RooAbsArg &v1)
union TClingDataMemberInfo::@38 fConstInitVal
#define assert(cond)
Definition: unittest.h:542
Small helper to keep current directory context.
TClingDataMemberInfo(cling::Interpreter *interp)
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...
llvm::StringRef DataMemberInfo__ValidArrayIndex(const clang::DeclaratorDecl &m, int *errnum=0, llvm::StringRef *errstr=0)
ValidArrayIndex return a static string (so use it or copy it immediatly, do not call GrabIndex twice ...
llvm::StringRef ValidArrayIndex() const
void GetFullyQualifiedTypeName(std::string &name, const clang::QualType &type, const cling::Interpreter &interpreter)
const clang::Type * GetType() const
clang::DeclContext::decl_iterator fIter
const void * DeclId_t
Definition: TDictionary.h:209
bool ExtractAttrPropertyFromName(const clang::Decl &decl, const std::string &propName, std::string &propValue)
This routine counts on the "propNamepropValue" format.
int extractAttrString(clang::Attr *attribute, std::string &attrString)
Extract attr string.
static const std::string separator("@@@")
TText * tt
Definition: textangle.C:16
#define CAT(a, b)
Definition: macros.h:281
std::vector< clang::DeclContext::decl_iterator > fIterStack
Emulation of the CINT TypeInfo class.
const char * TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
const char * Float
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, etc.) and adding default template argument for all types except the STL collections where we remove the default template argument if any.
int MaxIndex(int dim) const
static double C[]
llvm::SmallVector< clang::DeclContext *, 2 > fContexts
void CheckForIoTypeAndName() const
const T * GetAnnotatedRedeclarable(const T *Redecl)
Definition: TMetaUtils.h:617
const clang::Decl * GetDecl() const
cling::Interpreter * fInterp
const clang::Decl * GetDecl() const
const char * TypeName() const
Definition: TCling.h:48
const clang::ValueDecl * fSingleDecl
Emulation of the CINT ClassInfo class.
Enum
Definition: load.cpp:93
TClingClassInfo * fClassInfo
static Vc_ALWAYS_INLINE int_v max(const int_v &x, const int_v &y)
Definition: vector.h:440
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...
const int increment
RooCmdArg Layout(Double_t xmin, Double_t xmax=0.99, Double_t ymin=0.95)
long Property() const
const char * cnt
Definition: TXMLSetup.cxx:75