Logo ROOT  
Reference Guide
TClingBaseClassInfo.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 TClingBaseClassInfo
13 
14 Emulation of the CINT BaseClassInfo class.
15 
16 The CINT C++ interpreter provides an interface to metadata about
17 the base classes of a class through the BaseClassInfo class. This
18 class provides the same functionality, using an interface as close
19 as possible to BaseClassInfo but the base class metadata comes from
20 the Clang C++ compiler, not CINT.
21 */
22 
23 #include "TClingBaseClassInfo.h"
24 
25 #include "TClingClassInfo.h"
26 #include "TDictionary.h"
27 #include "TClingUtils.h"
28 
29 #include "TError.h"
30 
31 #include "cling/Interpreter/Interpreter.h"
32 #include "cling/Interpreter/Transaction.h"
33 
34 
35 #include "clang/AST/ASTContext.h"
36 #include "clang/AST/Decl.h"
37 #include "clang/AST/DeclCXX.h"
38 #include "clang/AST/PrettyPrinter.h"
39 #include "clang/AST/RecordLayout.h"
40 #include "clang/AST/Type.h"
41 #include "clang/AST/CXXInheritance.h"
42 
43 
44 #include "llvm/Support/Casting.h"
45 #include "llvm/Support/raw_ostream.h"
46 #include "llvm/ExecutionEngine/ExecutionEngine.h"
47 #include "llvm/IR/Module.h"
48 
49 #include <string>
50 #include <sstream>
51 
52 using namespace llvm;
53 using namespace clang;
54 using namespace std;
55 
56 TClingBaseClassInfo::TClingBaseClassInfo(cling::Interpreter* interp,
57  TClingClassInfo* ci)
58  : fInterp(interp), fClassInfo(0), fFirstTime(true), fDescend(false),
59  fDecl(0), fIter(0), fBaseInfo(0), fOffset(0L), fClassInfoOwnership(true)
60 {
61  // Constructs a base class iterator on ci; ci == 0 means global scope (which
62  // is meaningless). The derived class info passed in as ci is copied.
63  if (!ci) {
64  fClassInfo = new TClingClassInfo(interp);
65  return;
66  }
67  fClassInfo = new TClingClassInfo(*ci);
68  if (!fClassInfo->GetDecl()) {
69  return;
70  }
71  const clang::CXXRecordDecl* CRD =
72  llvm::dyn_cast<clang::CXXRecordDecl>(fClassInfo->GetDecl());
73  if (!CRD) {
74  // We were initialized with something that is not a class.
75  // FIXME: We should prevent this from happening!
76  return;
77  }
78  fDecl = CRD;
79  {
80  // In particular if the base are templated, this might deserialize.
81  cling::Interpreter::PushTransactionRAII RAII(fInterp);
82  fIter = CRD->bases_begin();
83  }
84 }
85 
86 TClingBaseClassInfo::TClingBaseClassInfo(cling::Interpreter* interp,
87  TClingClassInfo* derived,
88  TClingClassInfo* base)
89  : fInterp(interp), fClassInfo(0), fFirstTime(true), fDescend(false),
90  fDecl(0), fIter(0), fBaseInfo(0), fOffset(0L), fClassInfoOwnership(false)
91 {
92  // Constructs a single base class base (no iterator) of derived; derived must be != 0.
93  // The derived class info is referenced during the lifetime of the TClingBaseClassInfo.
94  if (!derived->GetDecl()) {
95  return;
96  }
97  const clang::CXXRecordDecl* CRD =
98  llvm::dyn_cast<clang::CXXRecordDecl>(derived->GetDecl());
99  const clang::CXXRecordDecl* BaseCRD =
100  llvm::dyn_cast<clang::CXXRecordDecl>(base->GetDecl());
101  if (!CRD || !BaseCRD) {
102  // We were initialized with something that is not a class.
103  // FIXME: We should prevent this from happening!
104  return;
105  }
106 
107  fClassInfo = derived;
108  fDecl = CRD;
109  //CRD->isDerivedFrom(BaseCRD, Paths);
110  // Check that base derives from derived.
111  clang::CXXBasePaths Paths;
112 
113  // CXXRecordDecl::isDerivedFrom can trigger deserialization.
114  cling::Interpreter::PushTransactionRAII RAII(fInterp);
115 
116  if (!CRD->isDerivedFrom(BaseCRD, Paths)) {
117  //Not valid fBaseInfo = 0.
118  return;
119  }
120 
121  fBaseInfo = new TClingClassInfo(*base);
122  fIter = CRD->bases_end();
123 }
124 
126  : fInterp(rhs.fInterp), fClassInfo(0), fFirstTime(rhs.fFirstTime),
127  fDescend(rhs.fDescend), fDecl(rhs.fDecl), fIter(rhs.fIter), fBaseInfo(0),
128  fIterStack(rhs.fIterStack), fOffset(rhs.fOffset), fClassInfoOwnership(true)
129 {
130  // Copies a base class info including the base and derived class infos.
132  fBaseInfo = new TClingClassInfo(*rhs.fBaseInfo);
133 }
134 
136  const TClingBaseClassInfo& rhs)
137 {
138  if (this != &rhs) {
139  fInterp = rhs.fInterp;
141  delete fClassInfo;
143  fFirstTime = rhs.fFirstTime;
144  fDescend = rhs.fDescend;
145  fDecl = rhs.fDecl;
146  fIter = rhs.fIter;
147  delete fBaseInfo;
148  fBaseInfo = new TClingClassInfo(*rhs.fBaseInfo);
149  fIterStack = rhs.fIterStack;
150  fOffset = rhs.fOffset;
151  fClassInfoOwnership = true;
152  }
153  return *this;
154 }
155 
157 {
158  if (!IsValid()) {
159  return 0;
160  }
161  return fBaseInfo;
162 }
163 
166  TClingClassInfo* toBaseClass,
167  void* address, bool isDerivedObject) const
168 {
169  // Generate a function at run-time that would calculate the offset
170  // from the parameter derived class to the parameter toBase class for the
171  // address.
172 
173  // rootcling can trigger this, too, and without CodeGen we cannot use any
174  // offset calculation function.
175  if (fInterp->isInSyntaxOnlyMode())
176  return 0;
177 
178  // Get the dedcls for the two classes.
179  const clang::RecordDecl* fromDerivedDecl
180  = dyn_cast<clang::RecordDecl>(fromDerivedClass->GetDecl());
181  if (!fromDerivedDecl) {
182  ::Error("TClingBaseClassInfo::GenerateBaseOffsetFunction",
183  "Offset of non-class %s is ill-defined!", fromDerivedClass->Name());
184  return 0;
185  }
186  const clang::RecordDecl* toBaseDecl
187  = dyn_cast<clang::RecordDecl>(toBaseClass->GetDecl());
188  if (!toBaseDecl) {
189  ::Error("TClingBaseClassInfo::GenerateBaseOffsetFunction",
190  "Offset of non-class %s is ill-defined!", toBaseClass->Name());
191  return 0;
192  }
193 
194  // Make the wrapper name.
195  string wrapper_name;
196  {
197  ostringstream buf;
198  buf << "h" << fromDerivedDecl;
199  buf << '_';
200  buf << "h" << toBaseDecl;
201  wrapper_name = buf.str();
202  }
203  string code;
204  // Check whether the function was already generated.
205  if (!fInterp->getAddressOfGlobal(wrapper_name)) {
206  // Get the class or namespace name.
207  string fromDerivedClassName;
208  clang::QualType QTDerived(fromDerivedClass->GetType(), 0);
209  ROOT::TMetaUtils::GetFullyQualifiedTypeName(fromDerivedClassName,
210  QTDerived, *fInterp);
211  string toBase_class_name;
212  clang::QualType QTtoBase(toBaseClass->GetType(), 0);
214  QTtoBase, *fInterp);
215  // Write the wrapper code.
216  llvm::raw_string_ostream buf(code);
217  buf << "extern \"C\" long " + wrapper_name + "(void* address, bool isDerivedObject) {\n"
218  // If the object is not derived, will downcast to toBase first.
219  << " " << fromDerivedClassName << " *fromDerived;"
220  << " if (isDerivedObject) {"
221  << " fromDerived = (" << fromDerivedClassName << "*)address;\n"
222  << " } else {\n"
223  << " fromDerived = dynamic_cast<" << fromDerivedClassName << "*>((" << toBase_class_name << "*)address);\n"
224  << " }\n"
225  << " if (!fromDerived) {\n"
226  << " return -1; \n"
227  << " }\n"
228  << " " << toBase_class_name << " *toBase = fromDerived;\n"
229  << " return ((long)toBase - (long)fromDerived);\n}\n";
230  }
231 
232  // If we have a GV then compileFunction will use it; empty code is enough.
233  void* f = fInterp->compileFunction(wrapper_name, code, true /*ifUnique*/,
234  false /*withAccessControl*/);
235  if (!f) {
236  ::Error("TClingBaseClassInfo::GenerateBaseOffsetFunction",
237  "Compilation failed!");
238  return 0;
239  }
240 
241  return (OffsetPtrFunc_t) f;
242 }
243 
245 {
246  return
247  // inited with a valid class, and
248  fClassInfo->IsValid() &&
249  // the base class we are iterating over is valid, and
250  fDecl &&
251  // our current base has a TClingClassInfo, and
252  fBaseInfo &&
253  // our current base is a valid class
254  fBaseInfo->IsValid();
255 }
256 
258 {
259  // Exit early if the iterator is already invalid.
260  if (!fDecl || !fIter ||
261  (fIter == llvm::dyn_cast<clang::CXXRecordDecl>(fDecl)->bases_end())) {
262  return 0;
263  }
264 
265  // Advance to the next valid base.
266  while (1) {
267  // Advance the iterator.
268  if (fFirstTime) {
269  // The cint semantics are strange.
270  fFirstTime = false;
271  }
272  else if (!onlyDirect && fDescend) {
273  // We previously processed a base class which itself has bases,
274  // now we process the bases of that base class.
275 
276  // At least getASTRecordLayout() might deserialize.
277  cling::Interpreter::PushTransactionRAII RAII(fInterp);
278  fDescend = false;
279  const clang::RecordType *Ty = fIter->getType()->
280  getAs<clang::RecordType>();
281  // Note: We made sure this would work when we selected the
282  // base for processing.
283  clang::CXXRecordDecl *Base = llvm::cast<clang::CXXRecordDecl>(
284  Ty->getDecl()->getDefinition());
285  clang::ASTContext &Context = Base->getASTContext();
286  const clang::RecordDecl *RD = llvm::dyn_cast<clang::RecordDecl>(fDecl);
287  const clang::ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
288  int64_t offset = Layout.getBaseClassOffset(Base).getQuantity();
289  fOffset += static_cast<long>(offset);
290  fIterStack.push_back(std::make_pair(std::make_pair(fDecl, fIter),
291  static_cast<long>(offset)));
292  fDecl = Base;
293  fIter = Base->bases_begin();
294  }
295  else {
296  // Simple case, move on to the next base class specifier.
297  ++fIter;
298  }
299  // Fix it if we went past the end.
300  while (
301  (fIter == llvm::dyn_cast<clang::CXXRecordDecl>(fDecl)->bases_end()) &&
302  fIterStack.size()
303  ) {
304  // All done with this base class.
305  fDecl = fIterStack.back().first.first;
306  fIter = fIterStack.back().first.second;
307  fOffset -= fIterStack.back().second;
308  fIterStack.pop_back();
309  ++fIter;
310  }
311  // Check for final termination.
312  if (fIter == llvm::dyn_cast<clang::CXXRecordDecl>(fDecl)->bases_end()) {
313  // We have reached the end of the direct bases, all done.
314  delete fBaseInfo;
315  fBaseInfo = 0;
316  // Iterator is now invalid.
317  return 0;
318  }
319  // Check if current base class is a dependent type, that is, an
320  // uninstantiated template class.
321  const clang::TagType *Ty = fIter->getType()->getAs<clang::TagType>();
322  if (!Ty) {
323  // A dependent type (uninstantiated template), skip it.
324  continue;
325  }
326  // Check if current base class has a definition.
327  const clang::CXXRecordDecl *Base =
328  llvm::cast_or_null<clang::CXXRecordDecl>(Ty->getDecl()->
329  getDefinition());
330  if (!Base) {
331  // No definition yet (just forward declared), skip it.
332  continue;
333  }
334  // Now that we are going to return this base, check to see if
335  // we need to examine its bases next call.
336  if (!onlyDirect && Base->getNumBases()) {
337  fDescend = true;
338  }
339  // Update info for this base class.
340  delete fBaseInfo;
341  clang::QualType bType = ROOT::TMetaUtils::ReSubstTemplateArg(fIter->getType(),fClassInfo->GetType());
342  fBaseInfo = new TClingClassInfo(fInterp, *bType);
343  // Iterator is now valid.
344  return 1;
345  }
346 }
347 
348 int TClingBaseClassInfo::Next(int onlyDirect)
349 {
350  return InternalNext(onlyDirect);
351 }
352 
354 {
355  return Next(1);
356 }
357 
358 // This function is updating original one on http://clang.llvm.org/doxygen/CGExprCXX_8cpp_source.html#l01647
359 // To fit the needs.
360 static clang::CharUnits computeOffsetHint(clang::ASTContext &Context,
361  const clang::CXXRecordDecl *Src,
362  const clang::CXXRecordDecl *Dst,
363  cling::Interpreter* interp)
364 {
365  clang::CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
366  /*DetectVirtual=*/false);
367 
368  // If Dst is not derived from Src we can skip the whole computation below and
369  // return that Src is not a public base of Dst. Record all inheritance paths.
370  if (!Dst->isDerivedFrom(Src, Paths))
371  return clang::CharUnits::fromQuantity(-2);
372 
373  unsigned NumPublicPaths = 0;
374  clang::CharUnits Offset;
375 
376  // Now walk all possible inheritance paths.
377  for (clang::CXXBasePaths::paths_iterator I = Paths.begin(), E = Paths.end();
378  I != E; ++I) {
379 
380  ++NumPublicPaths;
381 
382  for (clang::CXXBasePath::iterator J = I->begin(), JE = I->end(); J != JE; ++J) {
383  // If the path contains a virtual base class we can't give any hint.
384  // -1: no hint.
385  if (J->Base->isVirtual())
386  return clang::CharUnits::fromQuantity(-1);
387 
388  if (NumPublicPaths > 1) // Won't use offsets, skip computation.
389  continue;
390 
391  // Accumulate the base class offsets.
392  cling::Interpreter::PushTransactionRAII RAII(interp);
393  const clang::ASTRecordLayout &L = Context.getASTRecordLayout(J->Class);
394  Offset += L.getBaseClassOffset(J->Base->getType()->getAsCXXRecordDecl());
395  }
396  }
397 
398  // -2: Src is not a public base of Dst.
399  if (NumPublicPaths == 0)
400  return clang::CharUnits::fromQuantity(-2);
401 
402  // -3: Src is a multiple public base type but never a virtual base type.
403  if (NumPublicPaths > 1)
404  return clang::CharUnits::fromQuantity(-3);
405 
406  // Otherwise, the Src type is a unique public nonvirtual base type of Dst.
407  // Return the offset of Src from the origin of Dst.
408  return Offset;
409  }
410 
411 ptrdiff_t TClingBaseClassInfo::Offset(void * address, bool isDerivedObject) const
412 {
413  // Compute the offset of the derived class to the base class.
414 
415  if (!IsValid()) {
416  return -1;
417  }
418  // Check if current base class has a definition.
419  const clang::CXXRecordDecl* Base =
420  llvm::cast_or_null<clang::CXXRecordDecl>(fBaseInfo->GetDecl());
421  if (!Base) {
422  // No definition yet (just forward declared), invalid.
423  return -1;
424  }
425  // If the base class has no virtual inheritance.
426  if (!(Property() & kIsVirtualBase)) {
427  clang::ASTContext& Context = Base->getASTContext();
428  const clang::CXXRecordDecl* RD = llvm::dyn_cast<clang::CXXRecordDecl>(fDecl);
429  if (!RD) {
430  // No RecordDecl for the class.
431  return -1;
432  }
433  long clang_val = computeOffsetHint(Context, Base, RD, fInterp).getQuantity();
434  if (clang_val == -2 || clang_val == -3) {
435  TString baseName;
436  TString derivedName;
437  {
438  // Need TNormalizedCtxt otherwise...
439  // Note: should we really be issuing a message here? Shouldn't
440  // the caller check and issue the message?
441  std::string buf;
442  PrintingPolicy Policy(fBaseInfo->GetDecl()->getASTContext().
443  getPrintingPolicy());
444  llvm::raw_string_ostream stream(buf);
445  ((const clang::NamedDecl*)fBaseInfo->GetDecl())
446  ->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
447  stream.flush();
448  baseName = buf;
449 
450  buf.clear();
451  ((const clang::NamedDecl*)fClassInfo->GetDecl())
452  ->getNameForDiagnostic(stream, Policy, /*Qualified=*/true);
453  stream.flush();
454  derivedName = buf;
455  }
456  if (clang_val == -2) {
457  ::Error("TClingBaseClassInfo::Offset",
458  "The class %s does not derive from the base %s.",
459  derivedName.Data(), baseName.Data());
460  } else {
461  // clang_val == -3
462  ::Error("TClingBaseClassInfo::Offset",
463  "There are multiple paths from derived class %s to base class %s.",
464  derivedName.Data(), baseName.Data());
465  }
466  clang_val = -1;
467  }
469  return clang_val;
470  }
471  // Verify the address of the instantiated object
472  if (!address) {
473  ::Error("TClingBaseClassInfo::Offset", "The address of the object for virtual base offset calculation is not valid.");
474  return -1;
475  }
476 
477  // Virtual inheritance case
478  OffsetPtrFunc_t executableFunc = GenerateBaseOffsetFunction(fClassInfo, fBaseInfo, address, isDerivedObject);
479  if (executableFunc) {
480  fClassInfo->AddBaseOffsetFunction(fBaseInfo->GetDecl(), executableFunc);
481  return (*executableFunc)(address, isDerivedObject);
482  }
483 
484  return -1;
485 }
486 
487 
489 {
490  if (!IsValid()) {
491  return 0L;
492  }
493  long property = 0L;
494 
495  if (fDecl == fClassInfo->GetDecl()) {
496  property |= kIsDirectInherit;
497  }
498 
499  const clang::CXXRecordDecl* CRD
500  = llvm::dyn_cast<CXXRecordDecl>(fDecl);
501  const clang::CXXRecordDecl* BaseCRD
502  = llvm::dyn_cast<CXXRecordDecl>(fBaseInfo->GetDecl());
503  if (!CRD || !BaseCRD) {
504  ::Error("TClingBaseClassInfo::Property",
505  "The derived class or the base class do not have a CXXRecordDecl.");
506  return property;
507  }
508 
509  clang::CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
510  /*DetectVirtual=*/true);
511  if (!CRD->isDerivedFrom(BaseCRD, Paths)) {
512  // Error really unexpected here, because construction / iteration guarantees
513  //inheritance;
514  ::Error("TClingBaseClassInfo", "Class not derived from given base.");
515  }
516  if (Paths.getDetectedVirtual()) {
517  property |= kIsVirtualBase;
518  }
519 
520  clang::AccessSpecifier AS = clang::AS_public;
521  // Derived: public Mid; Mid : protected Base: Derived inherits protected Base?
522  for (clang::CXXBasePaths::const_paths_iterator IB = Paths.begin(), EB = Paths.end();
523  AS != clang::AS_private && IB != EB; ++IB) {
524  switch (IB->Access) {
525  // keep AS unchanged?
526  case clang::AS_public: break;
527  case clang::AS_protected: AS = clang::AS_protected; break;
528  case clang::AS_private: AS = clang::AS_private; break;
529  case clang::AS_none: break;
530  }
531  }
532  switch (AS) {
533  case clang::AS_public:
534  property |= kIsPublic;
535  break;
536  case clang::AS_protected:
537  property |= kIsProtected;
538  break;
539  case clang::AS_private:
540  property |= kIsPrivate;
541  break;
542  case clang::AS_none:
543  // IMPOSSIBLE
544  break;
545  }
546  return property;
547 }
548 
550 {
551  if (!IsValid()) {
552  return -1L;
553  }
554  return fBaseInfo->Tagnum();
555 }
556 
558 {
559  if (!IsValid()) {
560  output.clear();
561  return;
562  }
563  fBaseInfo->FullName(output,normCtxt);
564 }
565 
566 const char* TClingBaseClassInfo::Name() const
567 {
568  if (!IsValid()) {
569  return 0;
570  }
571  return fBaseInfo->Name();
572 }
573 
575 {
576  if (!IsValid()) {
577  return 0;
578  }
579  return fBaseInfo->TmpltName();
580 }
581 
TClingBaseClassInfo::fClassInfoOwnership
bool fClassInfoOwnership
Definition: TClingBaseClassInfo.h:56
TClingBaseClassInfo::GetBase
TClingClassInfo * GetBase() const
Definition: TClingBaseClassInfo.cxx:156
llvm
Definition: TString.h:850
TClingBaseClassInfo::FullName
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Definition: TClingBaseClassInfo.cxx:557
TClingClassInfo::AddBaseOffsetValue
void AddBaseOffsetValue(const clang::Decl *decl, ptrdiff_t offset)
Definition: TClingClassInfo.cxx:132
f
#define f(i)
Definition: RSha256.hxx:122
TClingBaseClassInfo::fInterp
cling::Interpreter * fInterp
Definition: TClingBaseClassInfo.h:47
kIsPrivate
@ kIsPrivate
Definition: TDictionary.h:76
computeOffsetHint
static clang::CharUnits computeOffsetHint(clang::ASTContext &Context, const clang::CXXRecordDecl *Src, const clang::CXXRecordDecl *Dst, cling::Interpreter *interp)
Definition: TClingBaseClassInfo.cxx:360
TClingBaseClassInfo.h
TString::Data
const char * Data() const
Definition: TString.h:369
output
static void output(int code)
Definition: gifencode.c:226
TClingBaseClassInfo::fDescend
bool fDescend
Definition: TClingBaseClassInfo.h:50
ROOT::TMetaUtils::ReSubstTemplateArg
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...
Definition: TClingUtils.cxx:4541
TClingBaseClassInfo
Definition: TClingBaseClassInfo.h:43
RooFit::Offset
RooCmdArg Offset(Bool_t flag=kTRUE)
Definition: RooGlobalFunc.cxx:212
TClingBaseClassInfo::TClingBaseClassInfo
TClingBaseClassInfo(cling::Interpreter *, TClingClassInfo *)
Definition: TClingBaseClassInfo.cxx:56
ROOT::TMetaUtils::GetFullyQualifiedTypeName
void GetFullyQualifiedTypeName(std::string &name, const clang::QualType &type, const cling::Interpreter &interpreter)
Definition: TClingUtils.cxx:3501
TClingBaseClassInfo::fBaseInfo
TClingClassInfo * fBaseInfo
Definition: TClingBaseClassInfo.h:53
TClingBaseClassInfo::IsValid
bool IsValid() const
Definition: TClingBaseClassInfo.cxx:244
TClingBaseClassInfo::fIter
clang::CXXRecordDecl::base_class_const_iterator fIter
Definition: TClingBaseClassInfo.h:52
TClingClassInfo::FullName
void FullName(std::string &output, const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const
Definition: TClingClassInfo.cxx:1366
TString
Definition: TString.h:136
TClingClassInfo::TmpltName
const char * TmpltName() const
Definition: TClingClassInfo.cxx:1428
kIsVirtualBase
@ kIsVirtualBase
Definition: TDictionary.h:87
TClingBaseClassInfo::Tagnum
long Tagnum() const
Definition: TClingBaseClassInfo.cxx:549
kIsDirectInherit
@ kIsDirectInherit
Definition: TDictionary.h:82
TGeant4Unit::L
static constexpr double L
Definition: TGeant4SystemOfUnits.h:123
TDictionary.h
TClingClassInfo.h
TClingClassInfo::AddBaseOffsetFunction
void AddBaseOffsetFunction(const clang::Decl *decl, OffsetPtrFunc_t func)
Definition: TClingClassInfo.h:89
kIsProtected
@ kIsProtected
Definition: TDictionary.h:75
TClingBaseClassInfo::Next
int Next()
Definition: TClingBaseClassInfo.cxx:353
RooFit::Layout
RooCmdArg Layout(Double_t xmin, Double_t xmax=0.99, Double_t ymin=0.95)
Definition: RooGlobalFunc.cxx:217
TClingBaseClassInfo::fFirstTime
bool fFirstTime
Definition: TClingBaseClassInfo.h:49
TClingBaseClassInfo::Name
const char * Name() const
Definition: TClingBaseClassInfo.cxx:566
TClingBaseClassInfo::operator=
TClingBaseClassInfo & operator=(const TClingBaseClassInfo &)
Definition: TClingBaseClassInfo.cxx:135
TClingClassInfo
Definition: TClingClassInfo.h:58
OffsetPtrFunc_t
ptrdiff_t(* OffsetPtrFunc_t)(void *, bool)
Definition: TClingClassInfo.h:56
TClingClassInfo::Tagnum
long Tagnum() const
Definition: TClingClassInfo.cxx:1348
ROOT::TMetaUtils::TNormalizedCtxt
Definition: TClingUtils.h:138
TClingDeclInfo::IsValid
virtual bool IsValid() const
Definition: TClingDeclInfo.h:41
TClingBaseClassInfo::TmpltName
const char * TmpltName() const
Definition: TClingBaseClassInfo.cxx:574
TClingBaseClassInfo::Offset
ptrdiff_t Offset(void *address=0, bool isDerivedObject=true) const
Definition: TClingBaseClassInfo.cxx:411
TClingBaseClassInfo::fOffset
long fOffset
Definition: TClingBaseClassInfo.h:55
TClingClassInfo::GetType
const clang::Type * GetType() const
Definition: TClingClassInfo.h:129
clang
Definition: BaseSelectionRule.h:29
TClingBaseClassInfo::fClassInfo
TClingClassInfo * fClassInfo
Definition: TClingBaseClassInfo.h:48
kIsPublic
@ kIsPublic
Definition: TDictionary.h:74
TClingDeclInfo::Name
virtual const char * Name() const
Definition: TClingDeclInfo.cxx:29
TClingUtils.h
I
#define I(x, y, z)
TClingBaseClassInfo::fDecl
const clang::Decl * fDecl
Definition: TClingBaseClassInfo.h:51
TClingBaseClassInfo::GenerateBaseOffsetFunction
OffsetPtrFunc_t GenerateBaseOffsetFunction(TClingClassInfo *derivedClass, TClingClassInfo *targetClass, void *address, bool isDerivedObject) const
Definition: TClingBaseClassInfo.cxx:165
TClingBaseClassInfo::Property
long Property() const
Definition: TClingBaseClassInfo.cxx:488
TClingDeclInfo::GetDecl
virtual const clang::Decl * GetDecl() const
Definition: TClingDeclInfo.h:37
TClingBaseClassInfo::fIterStack
std::vector< std::pair< std::pair< const clang::Decl *, clang::CXXRecordDecl::base_class_const_iterator >, long > > fIterStack
Definition: TClingBaseClassInfo.h:54
TClingBaseClassInfo::InternalNext
int InternalNext(int onlyDirect)
Definition: TClingBaseClassInfo.cxx:257
TMath::E
constexpr Double_t E()
Base of natural log:
Definition: TMath.h:102
Error
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:188
TError.h
Dst
#define Dst
Definition: mesh.h:158