Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TClingDataMemberInfo.h
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 #ifndef ROOT_TClingDataMemberInfo
13 #define ROOT_TClingDataMemberInfo
14 
15 //////////////////////////////////////////////////////////////////////////
16 // //
17 // TClingDataMemberInfo //
18 // //
19 // Emulation of the CINT DataMemberInfo class. //
20 // //
21 // The CINT C++ interpreter provides an interface to metadata about //
22 // the data members of a class through the DataMemberInfo class. This //
23 // class provides the same functionality, using an interface as close //
24 // as possible to DataMemberInfo but the data member metadata comes //
25 // from the Clang C++ compiler, not CINT. //
26 // //
27 //////////////////////////////////////////////////////////////////////////
28 
29 #include "TClingClassInfo.h"
30 
31 #include "TClingDeclInfo.h"
32 
33 #include "cling/Interpreter/Interpreter.h"
34 
35 #include "clang/AST/ASTContext.h"
36 #include "clang/AST/Decl.h"
37 #include "clang/Frontend/CompilerInstance.h"
38 
39 #include <vector>
40 #include <string>
41 
42 namespace clang {
43  class Decl;
44  class ValueDecl;
45 }
46 
47 namespace ROOT {
48  namespace TMetaUtils {
49  class TNormalizedCtxt;
50  }
51 }
52 
53 class TClingClassInfo;
54 
55 class TClingDataMemberInfo final : public TClingDeclInfo {
56 
57 private:
58 
59  cling::Interpreter *fInterp; // Cling interpreter, we do *not* own.
60  TClingClassInfo *fClassInfo; // Class we are iterating over, we own.
61  bool fFirstTime; // We need to skip the first increment to support the cint Next() semantics.
62  clang::DeclContext::decl_iterator fIter; // Current decl.
63  std::vector<clang::DeclContext::decl_iterator> fIterStack; // Recursion stack for traversing nested transparent scopes.
64  std::string fTitle; // The meta info for the member.
65 
66  llvm::SmallVector<clang::DeclContext *, 2> fContexts; // Set of DeclContext that we will iterate over.
67 
68  unsigned int fContextIdx; // Index in fContexts of DeclContext we are iterating over.
69  mutable std::string fIoType;
70  mutable std::string fIoName;
71  union {
72  float fFloat;
73  double fDouble;
74  long fLong;
75  } fConstInitVal; // Result of VarDecl::evaluateValue()
76  inline void CheckForIoTypeAndName () const;
77 
78 public:
79 
80  ~TClingDataMemberInfo() { delete fClassInfo; }
81 
82  explicit TClingDataMemberInfo(cling::Interpreter *interp)
83  : TClingDeclInfo(nullptr), fInterp(interp), fClassInfo(0), fFirstTime(true), fContextIdx(0U)
84  {
85  fClassInfo = new TClingClassInfo(fInterp);
86  fIter = fInterp->getCI()->getASTContext().getTranslationUnitDecl()->decls_begin();
87  // Move to first global variable.
88  InternalNext();
89  }
90 
91  TClingDataMemberInfo(cling::Interpreter *, TClingClassInfo *);
92 
93  // Takes concrete decl and disables the iterator.
94  // ValueDecl is the common base between enum constant, var decl and field decl
95  TClingDataMemberInfo(cling::Interpreter *, const clang::ValueDecl *, TClingClassInfo *);
96 
97  TClingDataMemberInfo(const TClingDataMemberInfo &rhs):
98  TClingDeclInfo(rhs), fContextIdx(0)
99  {
100  fInterp = rhs.fInterp;
101  fClassInfo = new TClingClassInfo(*rhs.fClassInfo);
102  fFirstTime = rhs.fFirstTime;
103  fIter = rhs.fIter;
104  fIterStack = rhs.fIterStack;
105  fContexts = rhs.fContexts;
106  fContextIdx = rhs.fContextIdx;
107  }
108 
109  TClingDataMemberInfo &operator=(const TClingDataMemberInfo &rhs)
110  {
111  if (this != &rhs) {
112  fInterp = rhs.fInterp;
113  delete fClassInfo;
114  fClassInfo = new TClingClassInfo(*rhs.fClassInfo);
115  fFirstTime = rhs.fFirstTime;
116  fIter = rhs.fIter;
117  fIterStack = rhs.fIterStack;
118  fContexts = rhs.fContexts;
119  fContextIdx = rhs.fContextIdx;
120  }
121  return *this;
122  }
123 
124  typedef TDictionary::DeclId_t DeclId_t;
125 
126  int ArrayDim() const;
127  TClingClassInfo *GetClassInfo() const { return fClassInfo; }
128  const clang::Decl *GetDecl() const override {
129  if (const clang::Decl* SingleDecl = TClingDeclInfo::GetDecl())
130  return SingleDecl;
131  return *fIter;
132  }
133  DeclId_t GetDeclId() const;
134  int MaxIndex(int dim) const;
135  int InternalNext();
136  bool Next() { return InternalNext(); }
137  long Offset();
138  long Property() const;
139  long TypeProperty() const;
140  int TypeSize() const;
141  const char *TypeName() const;
142  const char *TypeTrueName(const ROOT::TMetaUtils::TNormalizedCtxt &normCtxt) const;
143  const char *Name() override;
144  const char *Title();
145  llvm::StringRef ValidArrayIndex() const;
146 
147 };
148 
149 #endif // ROOT_TClingDataMemberInfo