Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TClingClassInfo.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 TClingClassInfo
13 
14 Emulation of the CINT ClassInfo class.
15 
16 The CINT C++ interpreter provides an interface to metadata about
17 a class through the ClassInfo class. This class provides the same
18 functionality, using an interface as close as possible to ClassInfo
19 but the class metadata comes from the Clang C++ compiler, not CINT.
20 */
21 
22 #include "TClingClassInfo.h"
23 
24 #include "TClassEdit.h"
25 #include "TClingBaseClassInfo.h"
26 #include "TClingCallFunc.h"
27 #include "TClingMethodInfo.h"
28 #include "TDictionary.h"
29 #include "TClingTypeInfo.h"
30 #include "TError.h"
31 #include "TClingUtils.h"
32 #include "ThreadLocalStorage.h"
33 
34 #include "cling/Interpreter/Interpreter.h"
35 #include "cling/Interpreter/LookupHelper.h"
36 #include "cling/Utils/AST.h"
37 
38 #include "clang/AST/ASTContext.h"
39 #include "clang/AST/Decl.h"
40 #include "clang/AST/DeclCXX.h"
41 #include "clang/AST/DeclTemplate.h"
42 #include "clang/AST/GlobalDecl.h"
43 #include "clang/AST/PrettyPrinter.h"
44 #include "clang/AST/RecordLayout.h"
45 #include "clang/AST/Type.h"
46 #include "clang/Basic/Specifiers.h"
47 #include "clang/Frontend/CompilerInstance.h"
48 #include "clang/Sema/Sema.h"
49 
50 #include "llvm/ExecutionEngine/GenericValue.h"
51 #include "llvm/Support/Casting.h"
52 #include "llvm/Support/raw_ostream.h"
53 
54 #include <sstream>
55 #include <string>
56 
57 using namespace clang;
58 using namespace ROOT;
59 
60 static std::string FullyQualifiedName(const Decl *decl) {
61  // Return the fully qualified name without worrying about normalizing it.
62  std::string buf;
63  if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(decl)) {
64  PrintingPolicy Policy(decl->getASTContext().getPrintingPolicy());
65  llvm::raw_string_ostream stream(buf);
66  ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
67  }
68  return buf;
69 }
70 
71 TClingClassInfo::TClingClassInfo(cling::Interpreter *interp, Bool_t all)
72  : TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fDescend(false), fIterAll(all),
73  fIsIter(true), fType(0), fOffsetCache(0)
74 {
75  TranslationUnitDecl *TU =
76  interp->getCI()->getASTContext().getTranslationUnitDecl();
77  fFirstTime = true;
78  SetDecl(TU);
79  fType = 0;
80 }
81 
82 TClingClassInfo::TClingClassInfo(cling::Interpreter *interp, const char *name)
83  : TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fDescend(false), fIterAll(kTRUE), fIsIter(false),
84  fType(0), fTitle(""), fOffsetCache(0)
85 {
86  const cling::LookupHelper& lh = fInterp->getLookupHelper();
87  const Type *type = 0;
88  const Decl *decl = lh.findScope(name,
89  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
90  : cling::LookupHelper::NoDiagnostics,
91  &type, /* intantiateTemplate= */ true );
92  if (!decl) {
93  std::string buf = TClassEdit::InsertStd(name);
94  if (buf != name) {
95  decl = lh.findScope(buf,
96  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
97  : cling::LookupHelper::NoDiagnostics,
98  &type, /* intantiateTemplate= */ true );
99  }
100  }
101  if (!decl && type) {
102  const TagType *tagtype =type->getAs<TagType>();
103  if (tagtype) {
104  decl = tagtype->getDecl();
105  }
106  }
107  SetDecl(decl);
108  fType = type;
109  if (decl && decl->isInvalidDecl()) {
110  Error("TClingClassInfo", "Found an invalid decl for %s.",name);
111  SetDecl(nullptr);
112  fType = nullptr;
113  }
114 }
115 
116 TClingClassInfo::TClingClassInfo(cling::Interpreter *interp,
117  const Type &tag)
118  : TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fDescend(false), fIterAll(kTRUE),
119  fIsIter(false), fType(0), fTitle(""), fOffsetCache(0)
120 {
121  Init(tag);
122 }
123 
124 TClingClassInfo::TClingClassInfo(cling::Interpreter *interp,
125  const Decl *D)
126  : TClingDeclInfo(nullptr), fInterp(interp), fFirstTime(true), fDescend(false), fIterAll(kTRUE),
127  fIsIter(false), fType(0), fTitle(""), fOffsetCache(0)
128 {
129  Init(D);
130 }
131 
132 void TClingClassInfo::AddBaseOffsetValue(const clang::Decl* decl, ptrdiff_t offset)
133 {
134  // Add the offset value from this class to the non-virtual base class
135  // determined by the parameter decl.
136 
137  OffsetPtrFunc_t executableFunc = 0;
138  fOffsetCache[decl] = std::make_pair(offset, executableFunc);
139 }
140 
141 long TClingClassInfo::ClassProperty() const
142 {
143  if (!IsValid()) {
144  return 0L;
145  }
146  long property = 0L;
147  const RecordDecl *RD = llvm::dyn_cast<RecordDecl>(GetDecl());
148  if (!RD) {
149  // We are an enum or namespace.
150  // The cint interface always returns 0L for these guys.
151  return property;
152  }
153  if (RD->isUnion()) {
154  // The cint interface always returns 0L for these guys.
155  return property;
156  }
157  // We now have a class or a struct.
158  const CXXRecordDecl *CRD =
159  llvm::dyn_cast<CXXRecordDecl>(GetDecl());
160  property |= kClassIsValid;
161  if (CRD->isAbstract()) {
162  property |= kClassIsAbstract;
163  }
164  if (CRD->hasUserDeclaredConstructor()) {
165  property |= kClassHasExplicitCtor;
166  }
167  if (
168  !CRD->hasUserDeclaredConstructor() &&
169  !CRD->hasTrivialDefaultConstructor()
170  ) {
171  property |= kClassHasImplicitCtor;
172  }
173  if (
174  CRD->hasUserProvidedDefaultConstructor() ||
175  !CRD->hasTrivialDefaultConstructor()
176  ) {
177  property |= kClassHasDefaultCtor;
178  }
179  if (CRD->hasUserDeclaredDestructor()) {
180  property |= kClassHasExplicitDtor;
181  }
182  else if (!CRD->hasTrivialDestructor()) {
183  property |= kClassHasImplicitDtor;
184  }
185  if (CRD->hasUserDeclaredCopyAssignment()) {
186  property |= kClassHasAssignOpr;
187  }
188  if (CRD->isPolymorphic()) {
189  property |= kClassHasVirtual;
190  }
191  return property;
192 }
193 
194 void TClingClassInfo::Delete(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
195 {
196  // Invoke operator delete on a pointer to an object
197  // of this class type.
198  if (!IsValid()) {
199  Error("TClingClassInfo::Delete()", "Called while invalid!");
200  return;
201  }
202  if (!IsLoaded()) {
203  Error("TClingClassInfo::Delete()", "Class is not loaded: %s",
204  FullyQualifiedName(GetDecl()).c_str());
205  return;
206  }
207  TClingCallFunc cf(fInterp,normCtxt);
208  cf.ExecDestructor(this, arena, /*nary=*/0, /*withFree=*/true);
209 }
210 
211 void TClingClassInfo::DeleteArray(void *arena, bool dtorOnly, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
212 {
213  // Invoke operator delete[] on a pointer to an array object
214  // of this class type.
215  if (!IsLoaded()) {
216  return;
217  }
218  if (dtorOnly) {
219  // There is no syntax in C++ for invoking the placement delete array
220  // operator, so we have to placement destroy each element by hand.
221  // Unfortunately we do not know how many elements to delete.
222  //TClingCallFunc cf(fInterp);
223  //cf.ExecDestructor(this, arena, nary, /*withFree=*/false);
224  Error("DeleteArray", "Placement delete of an array is unsupported!\n");
225  return;
226  }
227  TClingCallFunc cf(fInterp,normCtxt);
228  cf.ExecDestructor(this, arena, /*nary=*/1, /*withFree=*/true);
229 }
230 
231 void TClingClassInfo::Destruct(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
232 {
233  // Invoke placement operator delete on a pointer to an array object
234  // of this class type.
235  if (!IsLoaded()) {
236  return;
237  }
238  TClingCallFunc cf(fInterp,normCtxt);
239  cf.ExecDestructor(this, arena, /*nary=*/0, /*withFree=*/false);
240 }
241 
242 const FunctionTemplateDecl *TClingClassInfo::GetFunctionTemplate(const char *fname) const
243 {
244  // Return any method or function in this scope with the name 'fname'.
245 
246  if (!IsLoaded()) {
247  return 0;
248  }
249 
250  if (fType) {
251  const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
252  if (TT) {
253  llvm::StringRef tname(TT->getDecl()->getName());
254  if (tname.equals(fname)) {
255  const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(GetDecl());
256  if (ndecl && !ndecl->getName().equals(fname)) {
257  // Constructor name matching the typedef type, use the decl name instead.
258  return GetFunctionTemplate(ndecl->getName().str().c_str());
259  }
260  }
261  }
262  }
263  const cling::LookupHelper &lh = fInterp->getLookupHelper();
264  const FunctionTemplateDecl *fd
265  = lh.findFunctionTemplate(GetDecl(), fname,
266  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
267  : cling::LookupHelper::NoDiagnostics, false);
268  if (fd) return fd->getCanonicalDecl();
269  return 0;
270 }
271 
272 const clang::ValueDecl *TClingClassInfo::GetDataMember(const char *name) const
273 {
274  // Return the value decl (if any) corresponding to a data member which
275  // the given name declared in this scope.
276 
277  const cling::LookupHelper &lh = fInterp->getLookupHelper();
278  const ValueDecl *vd
279  = lh.findDataMember(GetDecl(), name,
280  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
281  : cling::LookupHelper::NoDiagnostics);
282  if (vd) return llvm::dyn_cast<ValueDecl>(vd->getCanonicalDecl());
283  else return 0;
284 }
285 
286 TClingMethodInfo TClingClassInfo::GetMethod(const char *fname) const
287 {
288  // Return any method or function in this scope with the name 'fname'.
289 
290  if (!IsLoaded()) {
291  TClingMethodInfo tmi(fInterp);
292  return tmi;
293  }
294 
295  R__LOCKGUARD(gInterpreterMutex);
296 
297  if (fType) {
298  const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
299  if (TT) {
300  llvm::StringRef tname(TT->getDecl()->getName());
301  if (tname.equals(fname)) {
302  const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(GetDecl());
303  if (ndecl && !ndecl->getName().equals(fname)) {
304  // Constructor name matching the typedef type, use the decl name instead.
305  return GetMethod(ndecl->getName().str().c_str());
306  }
307  }
308  }
309  }
310  const cling::LookupHelper &lh = fInterp->getLookupHelper();
311  const FunctionDecl *fd
312  = lh.findAnyFunction(GetDecl(), fname,
313  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
314  : cling::LookupHelper::NoDiagnostics,
315  false);
316  if (!fd) {
317  // Function not found.
318  TClingMethodInfo tmi(fInterp);
319  return tmi;
320  }
321  TClingMethodInfo tmi(fInterp);
322  tmi.Init(fd);
323  return tmi;
324 }
325 
326 TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
327  const char *proto, long *poffset, EFunctionMatchMode mode /*= kConversionMatch*/,
328  EInheritanceMode imode /*= kWithInheritance*/) const
329 {
330  return GetMethod(fname,proto,false,poffset,mode,imode);
331 }
332 
333 TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
334  const char *proto, bool objectIsConst,
335  long *poffset, EFunctionMatchMode mode /*= kConversionMatch*/,
336  EInheritanceMode imode /*= kWithInheritance*/) const
337 {
338  if (poffset) {
339  *poffset = 0L;
340  }
341  if (!IsLoaded()) {
342  TClingMethodInfo tmi(fInterp);
343  return tmi;
344  }
345 
346  R__LOCKGUARD(gInterpreterMutex);
347 
348  if (fType) {
349  const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
350  if (TT) {
351  llvm::StringRef tname(TT->getDecl()->getName());
352  if (tname.equals(fname)) {
353  const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(GetDecl());
354  if (ndecl && !ndecl->getName().equals(fname)) {
355  // Constructor name matching the typedef type, use the decl name instead.
356  return GetMethod(ndecl->getName().str().c_str(),proto,
357  objectIsConst,poffset,
358  mode,imode);
359  }
360  }
361  }
362 
363  }
364  const cling::LookupHelper& lh = fInterp->getLookupHelper();
365  const FunctionDecl *fd;
366  if (mode == kConversionMatch) {
367  fd = lh.findFunctionProto(GetDecl(), fname, proto,
368  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
369  : cling::LookupHelper::NoDiagnostics,
370  objectIsConst);
371  } else if (mode == kExactMatch) {
372  fd = lh.matchFunctionProto(GetDecl(), fname, proto,
373  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
374  : cling::LookupHelper::NoDiagnostics,
375  objectIsConst);
376  } else {
377  Error("TClingClassInfo::GetMethod",
378  "The MatchMode %d is not supported.", mode);
379  TClingMethodInfo tmi(fInterp);
380  return tmi;
381  }
382  if (!fd) {
383  // Function not found.
384  TClingMethodInfo tmi(fInterp);
385  return tmi;
386  }
387  if (imode == TClingClassInfo::kInThisScope) {
388  // If requested, check whether fd is a member function of this class.
389  // Even though this seems to be the wrong order (we should not allow the
390  // lookup to even collect candidates from the base) it does the right
391  // thing: if any function overload exists in the derived class, all
392  // (but explicitly used) will be hidden. Thus we will only find the
393  // derived class's function overloads (or used, which is fine). Only
394  // if there is none will we find those from the base, in which case
395  // we will reject them here:
396  const clang::DeclContext* ourDC = llvm::dyn_cast<clang::DeclContext>(GetDecl());
397  if (!fd->getDeclContext()->Equals(ourDC)
398  && !(fd->getDeclContext()->isTransparentContext()
399  && fd->getDeclContext()->getParent()->Equals(ourDC)))
400  return TClingMethodInfo(fInterp);
401 
402  // The offset must be 0 - the function must be ours.
403  if (poffset) *poffset = 0;
404  } else {
405  if (poffset) {
406  // We have been asked to return a this pointer adjustment.
407  if (const CXXMethodDecl *md =
408  llvm::dyn_cast<CXXMethodDecl>(fd)) {
409  // This is a class member function.
410  *poffset = GetOffset(md);
411  }
412  }
413  }
414  TClingMethodInfo tmi(fInterp);
415  tmi.Init(fd);
416  return tmi;
417 }
418 
419 TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
420  const llvm::SmallVectorImpl<clang::QualType> &proto,
421  long *poffset, EFunctionMatchMode mode /*= kConversionMatch*/,
422  EInheritanceMode imode /*= kWithInheritance*/) const
423 {
424  return GetMethod(fname,proto,false,poffset,mode,imode);
425 }
426 
427 TClingMethodInfo TClingClassInfo::GetMethod(const char *fname,
428  const llvm::SmallVectorImpl<clang::QualType> &proto, bool objectIsConst,
429  long *poffset, EFunctionMatchMode mode /*= kConversionMatch*/,
430  EInheritanceMode imode /*= kWithInheritance*/) const
431 {
432  if (poffset) {
433  *poffset = 0L;
434  }
435  if (!IsLoaded()) {
436  TClingMethodInfo tmi(fInterp);
437  return tmi;
438  }
439 
440  R__LOCKGUARD(gInterpreterMutex);
441 
442  if (fType) {
443  const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
444  if (TT) {
445  llvm::StringRef tname(TT->getDecl()->getName());
446  if (tname.equals(fname)) {
447  const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(GetDecl());
448  if (ndecl && !ndecl->getName().equals(fname)) {
449  // Constructor name matching the typedef type, use the decl name instead.
450  return GetMethod(ndecl->getName().str().c_str(),proto,objectIsConst,poffset,
451  mode,imode);
452  }
453  }
454  }
455 
456  }
457  const cling::LookupHelper& lh = fInterp->getLookupHelper();
458  const FunctionDecl *fd;
459  if (mode == kConversionMatch) {
460  fd = lh.findFunctionProto(GetDecl(), fname, proto,
461  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
462  : cling::LookupHelper::NoDiagnostics,
463  objectIsConst);
464  } else if (mode == kExactMatch) {
465  fd = lh.matchFunctionProto(GetDecl(), fname, proto,
466  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
467  : cling::LookupHelper::NoDiagnostics,
468  objectIsConst);
469  } else {
470  Error("TClingClassInfo::GetMethod",
471  "The MatchMode %d is not supported.", mode);
472  TClingMethodInfo tmi(fInterp);
473  return tmi;
474  }
475  if (!fd) {
476  // Function not found.
477  TClingMethodInfo tmi(fInterp);
478  return tmi;
479  }
480  if (poffset) {
481  // We have been asked to return a this pointer adjustment.
482  if (const CXXMethodDecl *md =
483  llvm::dyn_cast<CXXMethodDecl>(fd)) {
484  // This is a class member function.
485  *poffset = GetOffset(md);
486  }
487  }
488  TClingMethodInfo tmi(fInterp);
489  tmi.Init(fd);
490  return tmi;
491 }
492 
493 TClingMethodInfo TClingClassInfo::GetMethodWithArgs(const char *fname,
494  const char *arglist, long *poffset, EFunctionMatchMode mode /* = kConversionMatch*/,
495  EInheritanceMode imode /* = kWithInheritance*/) const
496 {
497  return GetMethodWithArgs(fname,arglist,false,poffset,mode,imode);
498 }
499 
500 TClingMethodInfo TClingClassInfo::GetMethodWithArgs(const char *fname,
501  const char *arglist, bool objectIsConst,
502  long *poffset, EFunctionMatchMode /*mode = kConversionMatch*/,
503  EInheritanceMode /* imode = kWithInheritance*/) const
504 {
505 
506  R__LOCKGUARD(gInterpreterMutex);
507 
508  if (fType) {
509  const TypedefType *TT = llvm::dyn_cast<TypedefType>(fType);
510  if (TT) {
511  llvm::StringRef tname(TT->getDecl()->getName());
512  if (tname.equals(fname)) {
513  const NamedDecl *ndecl = llvm::dyn_cast<NamedDecl>(GetDecl());
514  if (ndecl && !ndecl->getName().equals(fname)) {
515  // Constructor name matching the typedef type, use the decl name instead.
516  return GetMethod(ndecl->getName().str().c_str(),arglist,
517  objectIsConst,poffset
518  /* ,mode,imode */);
519  }
520  }
521  }
522 
523  }
524  if (poffset) {
525  *poffset = 0L;
526  }
527  if (!IsLoaded()) {
528  TClingMethodInfo tmi(fInterp);
529  return tmi;
530  }
531  if (!strcmp(arglist, ")")) {
532  // CINT accepted a single right paren as meaning no arguments.
533  arglist = "";
534  }
535  const cling::LookupHelper &lh = fInterp->getLookupHelper();
536  const FunctionDecl *fd
537  = lh.findFunctionArgs(GetDecl(), fname, arglist,
538  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
539  : cling::LookupHelper::NoDiagnostics,
540  objectIsConst);
541  if (!fd) {
542  // Function not found.
543  TClingMethodInfo tmi(fInterp);
544  return tmi;
545  }
546  if (poffset) {
547  // We have been asked to return a this pointer adjustment.
548  if (const CXXMethodDecl *md =
549  llvm::dyn_cast<CXXMethodDecl>(fd)) {
550  // This is a class member function.
551  *poffset = GetOffset(md);
552  }
553  }
554  TClingMethodInfo tmi(fInterp);
555  tmi.Init(fd);
556  return tmi;
557 }
558 
559 int TClingClassInfo::GetMethodNArg(const char *method, const char *proto,
560  Bool_t objectIsConst,
561  EFunctionMatchMode mode /*= kConversionMatch*/) const
562 {
563  // Note: Used only by TQObject.cxx:170 and only for interpreted classes.
564  if (!IsLoaded()) {
565  return -1;
566  }
567 
568  R__LOCKGUARD(gInterpreterMutex);
569 
570  TClingMethodInfo mi = GetMethod(method, proto, objectIsConst, 0, mode);
571  int clang_val = -1;
572  if (mi.IsValid()) {
573  unsigned num_params = mi.GetMethodDecl()->getNumParams();
574  clang_val = static_cast<int>(num_params);
575  }
576  return clang_val;
577 }
578 
579 long TClingClassInfo::GetOffset(const CXXMethodDecl* md) const
580 {
581 
582  R__LOCKGUARD(gInterpreterMutex);
583 
584  long offset = 0L;
585  const CXXRecordDecl* definer = md->getParent();
586  const CXXRecordDecl* accessor =
587  llvm::cast<CXXRecordDecl>(GetDecl());
588  if (definer != accessor) {
589  // This function may not be accessible using a pointer
590  // to the declaring class, get the adjustment necessary
591  // to convert that to a pointer to the defining class.
592  TClingBaseClassInfo bi(fInterp, const_cast<TClingClassInfo*>(this));
593  while (bi.Next(0)) {
594  TClingClassInfo* bci = bi.GetBase();
595  if (bci->GetDecl() == definer) {
596  // We have found the right base class, now get the
597  // necessary adjustment.
598  offset = bi.Offset();
599  break;
600  }
601  }
602  }
603  return offset;
604 }
605 
606 ptrdiff_t TClingClassInfo::GetBaseOffset(TClingClassInfo* base, void* address, bool isDerivedObject)
607 {
608 
609  {
610  R__READ_LOCKGUARD(ROOT::gCoreMutex);
611 
612  // Check for the offset in the cache.
613  auto iter = fOffsetCache.find(base->GetDecl());
614  if (iter != fOffsetCache.end()) {
615  std::pair<ptrdiff_t, OffsetPtrFunc_t> offsetCache = (*iter).second;
616  if (OffsetPtrFunc_t executableFunc = offsetCache.second) {
617  if (address) {
618  return (*executableFunc)(address, isDerivedObject);
619  }
620  else {
621  Error("TClingBaseClassInfo::Offset", "The address of the object for virtual base offset calculation is not valid.");
622  return -1;
623  }
624  }
625  else {
626  return offsetCache.first;
627  }
628  }
629  }
630 
631  // Compute the offset.
632  R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
633  TClingBaseClassInfo binfo(fInterp, this, base);
634  return binfo.Offset(address, isDerivedObject);
635 }
636 
637 std::vector<std::string> TClingClassInfo::GetUsingNamespaces()
638 {
639  // Find and return all 'using' declarations of namespaces.
640  std::vector<std::string> res;
641 
642  R__LOCKGUARD(gInterpreterMutex);
643 
644  cling::Interpreter::PushTransactionRAII RAII(fInterp);
645  const auto DC = dyn_cast<DeclContext>(fDecl);
646  if (!DC)
647  return res;
648 
649  clang::PrintingPolicy policy(fDecl->getASTContext().getPrintingPolicy());
650  for (auto UD : DC->using_directives()) {
651  NamespaceDecl *NS = UD->getNominatedNamespace();
652  if (NS) {
653  std::string nsName;
654  llvm::raw_string_ostream stream(nsName);
655 
656  NS->getNameForDiagnostic(stream, policy, /*Qualified=*/true);
657 
658  stream.flush();
659  res.push_back(nsName);
660  }
661  }
662 
663  return res;
664 }
665 
666 bool TClingClassInfo::HasDefaultConstructor() const
667 {
668  // Return true if there a constructor taking no arguments (including
669  // a constructor that has defaults for all of its arguments) which
670  // is callable. Either it has a body, or it is trivial and the
671  // compiler elides it.
672  //
673  // Note: This is could enhanced to also know about the ROOT ioctor
674  // but this was not the case in CINT.
675  //
676  if (!IsLoaded()) {
677  return false;
678  }
679  const CXXRecordDecl* CRD = llvm::dyn_cast<CXXRecordDecl>(GetDecl());
680  if (!CRD) {
681  // Namespaces do not have constructors.
682  return false;
683  }
684  using namespace TMetaUtils;
685  const RConstructorType ioctortype("",*fInterp);
686  return EIOCtorCategory::kAbsent != CheckConstructor(CRD,ioctortype,*fInterp);
687 }
688 
689 bool TClingClassInfo::HasMethod(const char *name) const
690 {
691  R__LOCKGUARD(gInterpreterMutex);
692  if (IsLoaded() && !llvm::isa<EnumDecl>(GetDecl())) {
693  return fInterp->getLookupHelper()
694  .hasFunction(GetDecl(), name,
695  gDebug > 5 ? cling::LookupHelper::WithDiagnostics
696  : cling::LookupHelper::NoDiagnostics);
697  }
698  return false;
699 }
700 
701 void TClingClassInfo::Init(const char *name)
702 {
703  fFirstTime = true;
704  fDescend = false;
705  fIsIter = false;
706  fIter = DeclContext::decl_iterator();
707  SetDecl(nullptr);
708  fType = 0;
709  fIterStack.clear();
710  const cling::LookupHelper& lh = fInterp->getLookupHelper();
711  SetDecl(lh.findScope(name, gDebug > 5 ? cling::LookupHelper::WithDiagnostics
712  : cling::LookupHelper::NoDiagnostics,
713  &fType, /* intantiateTemplate= */ true ));
714  if (!GetDecl()) {
715  std::string buf = TClassEdit::InsertStd(name);
716  if (buf != name) {
717  SetDecl(lh.findScope(buf, gDebug > 5 ? cling::LookupHelper::WithDiagnostics
718  : cling::LookupHelper::NoDiagnostics,
719  &fType, /* intantiateTemplate= */ true ));
720  }
721  }
722  if (!GetDecl() && fType) {
723  const TagType *tagtype =fType->getAs<TagType>();
724  if (tagtype) {
725  SetDecl(tagtype->getDecl());
726  }
727  }
728 }
729 
730 void TClingClassInfo::Init(const Decl* decl)
731 {
732  fFirstTime = true;
733  fDescend = false;
734  fIsIter = false;
735  fIter = DeclContext::decl_iterator();
736  SetDecl(decl);
737  fType = 0;
738  fIterStack.clear();
739 }
740 
741 void TClingClassInfo::Init(int tagnum)
742 {
743  Fatal("TClingClassInfo::Init(tagnum)", "Should no longer be called");
744  return;
745 }
746 
747 void TClingClassInfo::Init(const Type &tag)
748 {
749  fType = &tag;
750 
751  R__LOCKGUARD(gInterpreterMutex);
752 
753  const TagType *tagtype = fType->getAs<TagType>();
754  if (tagtype) {
755  SetDecl(tagtype->getDecl());
756  }
757  else {
758  SetDecl(nullptr);
759  }
760  if (!GetDecl()) {
761  QualType qType(fType,0);
762  static PrintingPolicy printPol(fInterp->getCI()->getLangOpts());
763  printPol.SuppressScope = false;
764  Error("TClingClassInfo::Init(const Type&)",
765  "The given type %s does not point to a Decl",
766  qType.getAsString(printPol).c_str());
767  }
768 }
769 
770 bool TClingClassInfo::IsBase(const char *name) const
771 {
772  if (!IsLoaded()) {
773  return false;
774  }
775  TClingClassInfo base(fInterp, name);
776  if (!base.IsValid()) {
777  return false;
778  }
779 
780  R__LOCKGUARD(gInterpreterMutex);
781 
782  const CXXRecordDecl *CRD =
783  llvm::dyn_cast<CXXRecordDecl>(GetDecl());
784  if (!CRD) {
785  // We are an enum, namespace, or translation unit,
786  // we cannot be the base of anything.
787  return false;
788  }
789  const CXXRecordDecl *baseCRD =
790  llvm::dyn_cast<CXXRecordDecl>(base.GetDecl());
791  return CRD->isDerivedFrom(baseCRD);
792 }
793 
794 bool TClingClassInfo::IsEnum(cling::Interpreter *interp, const char *name)
795 {
796  // Note: This is a static member function.
797  TClingClassInfo info(interp, name);
798  if (info.IsValid() && (info.Property() & kIsEnum)) {
799  return true;
800  }
801  return false;
802 }
803 
804 bool TClingClassInfo::IsScopedEnum() const
805 {
806  if (auto *ED = llvm::dyn_cast<clang::EnumDecl>(GetDecl()))
807  return ED->isScoped();
808  return false;
809 }
810 
811 EDataType TClingClassInfo::GetUnderlyingType() const
812 {
813  if (!IsValid())
814  return kNumDataTypes;
815  if (GetDecl() == 0)
816  return kNumDataTypes;
817 
818  if (auto ED = llvm::dyn_cast<EnumDecl>(GetDecl())) {
819  R__LOCKGUARD(gInterpreterMutex);
820  auto Ty = ED->getIntegerType().getTypePtrOrNull();
821  if (auto BTy = llvm::dyn_cast<BuiltinType>(Ty)) {
822  switch (BTy->getKind()) {
823  case BuiltinType::Bool:
824  return kBool_t;
825 
826  case BuiltinType::Char_U:
827  case BuiltinType::UChar:
828  return kUChar_t;
829 
830  case BuiltinType::Char_S:
831  case BuiltinType::SChar:
832  return kChar_t;
833 
834  case BuiltinType::UShort:
835  return kUShort_t;
836  case BuiltinType::Short:
837  return kShort_t;
838  case BuiltinType::UInt:
839  return kUInt_t;
840  case BuiltinType::Int:
841  return kInt_t;
842  case BuiltinType::ULong:
843  return kULong_t;
844  case BuiltinType::Long:
845  return kLong_t;
846  case BuiltinType::ULongLong:
847  return kULong64_t;
848  case BuiltinType::LongLong:
849  return kLong64_t;
850  default:
851  return kNumDataTypes;
852  };
853  }
854  }
855  return kNumDataTypes;
856 }
857 
858 
859 bool TClingClassInfo::IsLoaded() const
860 {
861  // IsLoaded in CINT was meaning is known to the interpreter
862  // and has a complete definition.
863  // IsValid in Cling (as in CING) means 'just' is known to the
864  // interpreter.
865  if (!IsValid()) {
866  return false;
867  }
868  if (GetDecl() == 0) {
869  return false;
870  }
871 
872  R__LOCKGUARD(gInterpreterMutex);
873 
874  const CXXRecordDecl *CRD = llvm::dyn_cast<CXXRecordDecl>(GetDecl());
875  if ( CRD ) {
876  if (!CRD->hasDefinition()) {
877  return false;
878  }
879  } else {
880  const TagDecl *TD = llvm::dyn_cast<TagDecl>(GetDecl());
881  if (TD && TD->getDefinition() == 0) {
882  return false;
883  }
884  }
885  // All clang classes are considered loaded.
886  return true;
887 }
888 
889 bool TClingClassInfo::IsValidMethod(const char *method, const char *proto,
890  Bool_t objectIsConst,
891  long *offset,
892  EFunctionMatchMode mode /*= kConversionMatch*/) const
893 {
894  // Check if the method with the given prototype exist.
895  if (!IsLoaded()) {
896  return false;
897  }
898  if (offset) {
899  *offset = 0L;
900  }
901  TClingMethodInfo mi = GetMethod(method, proto, offset, mode);
902  return mi.IsValid();
903 }
904 
905 int TClingClassInfo::InternalNext()
906 {
907  R__LOCKGUARD(gInterpreterMutex);
908 
909  fDeclFileName.clear(); // invalidate decl file name.
910  fNameCache.clear(); // invalidate the cache.
911 
912  cling::Interpreter::PushTransactionRAII RAII(fInterp);
913  if (fFirstTime) {
914  // GetDecl() must be a DeclContext in order to iterate.
915  const clang::DeclContext *DC = cast<DeclContext>(GetDecl());
916  if (fIterAll)
917  fIter = DC->decls_begin();
918  else
919  fIter = DC->noload_decls_begin();
920  }
921 
922  if (!fIsIter) {
923  // Object was not setup for iteration.
924  if (GetDecl()) {
925  std::string buf;
926  if (const NamedDecl* ND =
927  llvm::dyn_cast<NamedDecl>(GetDecl())) {
928  PrintingPolicy Policy(GetDecl()->getASTContext().
929  getPrintingPolicy());
930  llvm::raw_string_ostream stream(buf);
931  ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/false);
932  }
933  Error("TClingClassInfo::InternalNext",
934  "Next called but iteration not prepared for %s!", buf.c_str());
935  } else {
936  Error("TClingClassInfo::InternalNext",
937  "Next called but iteration not prepared!");
938  }
939  return 0;
940  }
941  while (true) {
942  // Advance to next usable decl, or return if there is no next usable decl.
943  if (fFirstTime) {
944  // The cint semantics are strange.
945  fFirstTime = false;
946  if (!*fIter) {
947  return 0;
948  }
949  }
950  else {
951  // Advance the iterator one decl, descending into the current decl
952  // context if necessary.
953  if (!fDescend) {
954  // Do not need to scan the decl context of the current decl,
955  // move on to the next decl.
956  ++fIter;
957  }
958  else {
959  // Descend into the decl context of the current decl.
960  fDescend = false;
961  //fprintf(stderr,
962  // "TClingClassInfo::InternalNext: "
963  // "pushing ...\n");
964  fIterStack.push_back(fIter);
965  DeclContext *DC = llvm::cast<DeclContext>(*fIter);
966  if (fIterAll)
967  fIter = DC->decls_begin();
968  else
969  fIter = DC->noload_decls_begin();
970  }
971  // Fix it if we went past the end.
972  while (!*fIter && fIterStack.size()) {
973  //fprintf(stderr,
974  // "TClingClassInfo::InternalNext: "
975  // "popping ...\n");
976  fIter = fIterStack.back();
977  fIterStack.pop_back();
978  ++fIter;
979  }
980  // Check for final termination.
981  if (!*fIter) {
982  // We have reached the end of the translation unit, all done.
983  SetDecl(nullptr);
984  fType = 0;
985  return 0;
986  }
987  }
988  // Return if this decl is a class, struct, union, enum, or namespace.
989  Decl::Kind DK = fIter->getKind();
990  if ((DK == Decl::Namespace) || (DK == Decl::Enum) ||
991  (DK == Decl::CXXRecord) ||
992  (DK == Decl::ClassTemplateSpecialization)) {
993  const TagDecl *TD = llvm::dyn_cast<TagDecl>(*fIter);
994  if (TD && !TD->isCompleteDefinition()) {
995  // For classes and enums, stop only on definitions.
996  continue;
997  }
998  if (DK == Decl::Namespace) {
999  // For namespaces, stop only on the first definition.
1000  if (!fIter->isCanonicalDecl()) {
1001  // Not the first definition.
1002  fDescend = true;
1003  continue;
1004  }
1005  }
1006  if (DK != Decl::Enum) {
1007  // We do not descend into enums.
1008  DeclContext *DC = llvm::cast<DeclContext>(*fIter);
1009  if ((fIterAll && *DC->decls_begin())
1010  || (!fIterAll && *DC->noload_decls_begin())) {
1011  // Next iteration will begin scanning the decl context
1012  // contained by this decl.
1013  fDescend = true;
1014  }
1015  }
1016  // Iterator is now valid.
1017  SetDecl(*fIter);
1018  fType = 0;
1019  if (GetDecl()) {
1020  if (GetDecl()->isInvalidDecl()) {
1021  Warning("TClingClassInfo::Next()","Reached an invalid decl.");
1022  }
1023  if (const RecordDecl *RD =
1024  llvm::dyn_cast<RecordDecl>(GetDecl())) {
1025  fType = RD->getASTContext().getRecordType(RD).getTypePtr();
1026  }
1027  }
1028  return 1;
1029  }
1030  }
1031 }
1032 
1033 int TClingClassInfo::Next()
1034 {
1035  return InternalNext();
1036 }
1037 
1038 void *TClingClassInfo::New(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
1039 {
1040  // Invoke a new expression to use the class constructor
1041  // that takes no arguments to create an object of this class type.
1042  if (!IsValid()) {
1043  Error("TClingClassInfo::New()", "Called while invalid!");
1044  return 0;
1045  }
1046  if (!IsLoaded()) {
1047  Error("TClingClassInfo::New()", "Class is not loaded: %s",
1048  FullyQualifiedName(GetDecl()).c_str());
1049  return 0;
1050  }
1051  {
1052  R__LOCKGUARD(gInterpreterMutex);
1053  const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(GetDecl());
1054  if (!RD) {
1055  Error("TClingClassInfo::New()", "This is a namespace!: %s",
1056  FullyQualifiedName(GetDecl()).c_str());
1057  return 0;
1058  }
1059  if (!HasDefaultConstructor()) {
1060  // FIXME: We fail roottest root/io/newdelete if we issue this message!
1061  //Error("TClingClassInfo::New()", "Class has no default constructor: %s",
1062  // FullyQualifiedName(GetDecl()).c_str());
1063  return 0;
1064  }
1065  } // End of Lock section.
1066  void* obj = 0;
1067  TClingCallFunc cf(fInterp,normCtxt);
1068  obj = cf.ExecDefaultConstructor(this, /*address=*/0, /*nary=*/0);
1069  if (!obj) {
1070  Error("TClingClassInfo::New()", "Call of default constructor "
1071  "failed to return an object for class: %s",
1072  FullyQualifiedName(GetDecl()).c_str());
1073  return 0;
1074  }
1075  return obj;
1076 }
1077 
1078 void *TClingClassInfo::New(int n, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
1079 {
1080  // Invoke a new expression to use the class constructor
1081  // that takes no arguments to create an array object
1082  // of this class type.
1083  if (!IsValid()) {
1084  Error("TClingClassInfo::New(n)", "Called while invalid!");
1085  return 0;
1086  }
1087  if (!IsLoaded()) {
1088  Error("TClingClassInfo::New(n)", "Class is not loaded: %s",
1089  FullyQualifiedName(GetDecl()).c_str());
1090  return 0;
1091  }
1092 
1093  {
1094  R__LOCKGUARD(gInterpreterMutex);
1095 
1096  const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(GetDecl());
1097  if (!RD) {
1098  Error("TClingClassInfo::New(n)", "This is a namespace!: %s",
1099  FullyQualifiedName(GetDecl()).c_str());
1100  return 0;
1101  }
1102  if (!HasDefaultConstructor()) {
1103  // FIXME: We fail roottest root/io/newdelete if we issue this message!
1104  //Error("TClingClassInfo::New(n)",
1105  // "Class has no default constructor: %s",
1106  // FullyQualifiedName(GetDecl()).c_str());
1107  return 0;
1108  }
1109  } // End of Lock section.
1110  void* obj = 0;
1111  TClingCallFunc cf(fInterp,normCtxt);
1112  obj = cf.ExecDefaultConstructor(this, /*address=*/0,
1113  /*nary=*/(unsigned long)n);
1114  if (!obj) {
1115  Error("TClingClassInfo::New(n)", "Call of default constructor "
1116  "failed to return an array of class: %s",
1117  FullyQualifiedName(GetDecl()).c_str());
1118  return 0;
1119  }
1120  return obj;
1121 }
1122 
1123 void *TClingClassInfo::New(int n, void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
1124 {
1125  // Invoke a placement new expression to use the class
1126  // constructor that takes no arguments to create an
1127  // array of objects of this class type in the given
1128  // memory arena.
1129  if (!IsValid()) {
1130  Error("TClingClassInfo::New(n, arena)", "Called while invalid!");
1131  return 0;
1132  }
1133  if (!IsLoaded()) {
1134  Error("TClingClassInfo::New(n, arena)", "Class is not loaded: %s",
1135  FullyQualifiedName(GetDecl()).c_str());
1136  return 0;
1137  }
1138  {
1139  R__LOCKGUARD(gInterpreterMutex);
1140 
1141  const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(GetDecl());
1142  if (!RD) {
1143  Error("TClingClassInfo::New(n, arena)", "This is a namespace!: %s",
1144  FullyQualifiedName(GetDecl()).c_str());
1145  return 0;
1146  }
1147  if (!HasDefaultConstructor()) {
1148  // FIXME: We fail roottest root/io/newdelete if we issue this message!
1149  //Error("TClingClassInfo::New(n, arena)",
1150  // "Class has no default constructor: %s",
1151  // FullyQualifiedName(GetDecl()).c_str());
1152  return 0;
1153  }
1154  } // End of Lock section
1155  void* obj = 0;
1156  TClingCallFunc cf(fInterp,normCtxt);
1157  // Note: This will always return arena.
1158  obj = cf.ExecDefaultConstructor(this, /*address=*/arena,
1159  /*nary=*/(unsigned long)n);
1160  return obj;
1161 }
1162 
1163 void *TClingClassInfo::New(void *arena, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
1164 {
1165  // Invoke a placement new expression to use the class
1166  // constructor that takes no arguments to create an
1167  // object of this class type in the given memory arena.
1168  if (!IsValid()) {
1169  Error("TClingClassInfo::New(arena)", "Called while invalid!");
1170  return 0;
1171  }
1172  if (!IsLoaded()) {
1173  Error("TClingClassInfo::New(arena)", "Class is not loaded: %s",
1174  FullyQualifiedName(GetDecl()).c_str());
1175  return 0;
1176  }
1177  {
1178  R__LOCKGUARD(gInterpreterMutex);
1179 
1180  const CXXRecordDecl* RD = dyn_cast<CXXRecordDecl>(GetDecl());
1181  if (!RD) {
1182  Error("TClingClassInfo::New(arena)", "This is a namespace!: %s",
1183  FullyQualifiedName(GetDecl()).c_str());
1184  return 0;
1185  }
1186  if (!HasDefaultConstructor()) {
1187  // FIXME: We fail roottest root/io/newdelete if we issue this message!
1188  //Error("TClingClassInfo::New(arena)",
1189  // "Class has no default constructor: %s",
1190  // FullyQualifiedName(GetDecl()).c_str());
1191  return 0;
1192  }
1193  } // End of Locked section.
1194  void* obj = 0;
1195  TClingCallFunc cf(fInterp,normCtxt);
1196  // Note: This will always return arena.
1197  obj = cf.ExecDefaultConstructor(this, /*address=*/arena, /*nary=*/0);
1198  return obj;
1199 }
1200 
1201 long TClingClassInfo::Property() const
1202 {
1203  if (!IsValid()) {
1204  return 0L;
1205  }
1206 
1207  R__LOCKGUARD(gInterpreterMutex);
1208 
1209  long property = 0L;
1210  property |= kIsCPPCompiled;
1211 
1212  // Modules can deserialize while querying the various decls for information.
1213  cling::Interpreter::PushTransactionRAII RAII(fInterp);
1214 
1215  const clang::DeclContext *ctxt = GetDecl()->getDeclContext();
1216  clang::NamespaceDecl *std_ns =fInterp->getSema().getStdNamespace();
1217  while (! ctxt->isTranslationUnit()) {
1218  if (ctxt->Equals(std_ns)) {
1219  property |= kIsDefinedInStd;
1220  break;
1221  }
1222  ctxt = ctxt->getParent();
1223  }
1224  Decl::Kind DK = GetDecl()->getKind();
1225  if ((DK == Decl::Namespace) || (DK == Decl::TranslationUnit)) {
1226  property |= kIsNamespace;
1227  return property;
1228  }
1229  // Note: Now we have class, enum, struct, union only.
1230  const TagDecl *TD = llvm::dyn_cast<TagDecl>(GetDecl());
1231  if (!TD) {
1232  return 0L;
1233  }
1234  if (TD->isEnum()) {
1235  property |= kIsEnum;
1236  return property;
1237  }
1238  // Note: Now we have class, struct, union only.
1239  const CXXRecordDecl *CRD =
1240  llvm::dyn_cast<CXXRecordDecl>(GetDecl());
1241  if (CRD->isClass()) {
1242  property |= kIsClass;
1243  }
1244  else if (CRD->isStruct()) {
1245  property |= kIsStruct;
1246  }
1247  else if (CRD->isUnion()) {
1248  property |= kIsUnion;
1249  }
1250  if (CRD->hasDefinition() && CRD->isAbstract()) {
1251  property |= kIsAbstract;
1252  }
1253  return property;
1254 }
1255 
1256 int TClingClassInfo::RootFlag() const
1257 {
1258  if (!IsValid()) {
1259  return 0;
1260  }
1261  // FIXME: Implement this when rootcling provides the value.
1262  return 0;
1263 }
1264 
1265 int TClingClassInfo::Size() const
1266 {
1267  if (!IsValid()) {
1268  return -1;
1269  }
1270  if (!GetDecl()) {
1271  // A forward declared class.
1272  return 0;
1273  }
1274 
1275  R__LOCKGUARD(gInterpreterMutex);
1276 
1277  Decl::Kind DK = GetDecl()->getKind();
1278  if (DK == Decl::Namespace) {
1279  // Namespaces are special for cint.
1280  return 1;
1281  }
1282  else if (DK == Decl::Enum) {
1283  // Enums are special for cint.
1284  return 0;
1285  }
1286  const RecordDecl *RD = llvm::dyn_cast<RecordDecl>(GetDecl());
1287  if (!RD) {
1288  // Should not happen.
1289  return -1;
1290  }
1291  if (!RD->getDefinition()) {
1292  // Forward-declared class.
1293  return 0;
1294  }
1295  ASTContext &Context = GetDecl()->getASTContext();
1296  cling::Interpreter::PushTransactionRAII RAII(fInterp);
1297  const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
1298  int64_t size = Layout.getSize().getQuantity();
1299  int clang_size = static_cast<int>(size);
1300  return clang_size;
1301 }
1302 
1303 long TClingClassInfo::Tagnum() const
1304 {
1305  if (!IsValid()) {
1306  return -1L;
1307  }
1308  return reinterpret_cast<long>(GetDecl());
1309 }
1310 
1311 const char *TClingClassInfo::FileName()
1312 {
1313  if (!IsValid()) {
1314  return 0;
1315  }
1316  if (fDeclFileName.empty())
1317  fDeclFileName = ROOT::TMetaUtils::GetFileName(*GetDecl(), *fInterp);
1318  return fDeclFileName.c_str();
1319 }
1320 
1321 void TClingClassInfo::FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
1322 {
1323  // Return QualifiedName.
1324  output.clear();
1325  if (!IsValid()) {
1326  return;
1327  }
1328  if (fType) {
1329  QualType type(fType, 0);
1330  ROOT::TMetaUtils::GetNormalizedName(output, type, *fInterp, normCtxt);
1331  }
1332  else {
1333  if (const NamedDecl* ND =
1334  llvm::dyn_cast<NamedDecl>(GetDecl())) {
1335  PrintingPolicy Policy(GetDecl()->getASTContext().
1336  getPrintingPolicy());
1337  llvm::raw_string_ostream stream(output);
1338  ND->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
1339  }
1340  }
1341 }
1342 
1343 const char *TClingClassInfo::Title()
1344 {
1345  if (!IsValid()) {
1346  return 0;
1347  }
1348  // NOTE: We cannot cache the result, since we are really an iterator.
1349  // Try to get the comment either from the annotation or the header
1350  // file, if present.
1351  // Iterate over the redeclarations, we can have multiple definitions in the
1352  // redecl chain (came from merging of pcms).
1353 
1354  R__LOCKGUARD(gInterpreterMutex);
1355 
1356  if (const TagDecl *TD = llvm::dyn_cast<TagDecl>(GetDecl())) {
1357  if ( (TD = ROOT::TMetaUtils::GetAnnotatedRedeclarable(TD)) ) {
1358  if (AnnotateAttr *A = TD->getAttr<AnnotateAttr>()) {
1359  std::string attr = A->getAnnotation().str();
1360  if (attr.find(TMetaUtils::propNames::separator) != std::string::npos) {
1361  if (TMetaUtils::ExtractAttrPropertyFromName(*TD,TMetaUtils::propNames::comment,attr)) {
1362  fTitle = attr;
1363  return fTitle.c_str();
1364  }
1365  } else {
1366  fTitle = attr;
1367  return fTitle.c_str();
1368  }
1369  }
1370  }
1371  }
1372  // Try to get the comment from the header file, if present.
1373  // but not for decls from AST file, where rootcling would have
1374  // created an annotation
1375  const CXXRecordDecl *CRD =
1376  llvm::dyn_cast<CXXRecordDecl>(GetDecl());
1377  if (CRD && !CRD->isFromASTFile()) {
1378  fTitle = ROOT::TMetaUtils::GetClassComment(*CRD,0,*fInterp).str();
1379  }
1380  return fTitle.c_str();
1381 }
1382 
1383 const char *TClingClassInfo::TmpltName() const
1384 {
1385  if (!IsValid()) {
1386  return 0;
1387  }
1388 
1389  R__LOCKGUARD(gInterpreterMutex);
1390 
1391  // Note: This *must* be static/thread_local because we are returning a pointer inside it!
1392  TTHREAD_TLS_DECL( std::string, buf);
1393  buf.clear();
1394  if (const NamedDecl* ND = llvm::dyn_cast<NamedDecl>(GetDecl())) {
1395  // Note: This does *not* include the template arguments!
1396  buf = ND->getNameAsString();
1397  }
1398  return buf.c_str();
1399 }
1400