Logo ROOT  
Reference Guide
DictSelectionReader.h
Go to the documentation of this file.
1 // @(#)root/utils/src:$Id$
2 // Author: Danilo Piparo January 2014
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2011, 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/rootcint. *
10  *************************************************************************/
11 
12 #ifndef __DICTSELECTIONREADER__
13 #define __DICTSELECTIONREADER__
14 
15 #include "clang/AST/RecursiveASTVisitor.h"
16 
17 #include <llvm/ADT/StringMap.h>
18 
19 #include <set>
20 #include <unordered_set>
21 #include <string>
22 #include <unordered_map>
23 
24 class SelectionRules;
25 class ClassSelectionRule;
26 namespace ROOT {
27  namespace TMetaUtils {
28  class TNormalizedCtxt;
29  }
30 }
31 namespace cling {
32 class Interpreter;
33 }
34 
35 namespace clang {
36  class ASTContext;
37 // class DeclContext;
38  class NamespaceDecl;
39  class CXXRecordDecl;
40 }
41 
42 /**
43  * @file DictSelectionReader.h
44  * @author Danilo Piparo
45  * @date January 2014
46  * @brief Select classes and assign properties using C++ syntax.
47  *
48  * @details When generating dictionary information for a class,
49  * one sometimes wants to specify additional information
50  * beyond the class definition itself, for example, to specify
51  * that certain members are to be treated as transient by the persistency
52  * system. This can be done by associating a dictionary selection class
53  * with the class for which dictionary information is being generated.
54  * The contents of this selection class encode the additional information.
55  * Below, we first discuss how to associate a selection class
56  * with your class; then we list the current Set of information
57  * which may appear inside the selection class.
58  *
59  * The simplest case is for the case of a non-template class @c C.
60  * By default, the Name of the selection class is then
61  * @c ROOT::Meta::Selection::C. If you have such a class, it will be found
62  * automatically. If @c C is in a namespace, @c NS::C, then
63  * the selection class should be in the same namespace:
64  * @c ROOT::Meta::Selection::NS::C.
65  *
66  * Examples:
67  *
68  * The DictSelectionReader is used to create selection rules starting from
69  * C++ the constructs of the @c ROOT::Meta::Selection namespace. All rules
70  * are matching by name.
71  * A brief description of the operations that lead to class selection:
72  * 1. If a class declaration is present in the selection namespace, a class
73  * with the same name is selected outside the selection namespace.
74  * 2. If a template class declaration and a template instantiation is present
75  * in the selection namespace, all the instances of the template are
76  * selected outside the namespace.
77  *
78  * For example:
79  * @code
80  * [...]
81  * class classVanilla{};
82  * template <class A> class classTemplateVanilla {};
83  * classTemplateVanilla<char> t0;
84  * namespace ROOT {
85  * namespace Meta {
86  * namespace Selection {
87  * class classVanilla {};
88  * template <typename A> class classTemplateVanilla {};
89  * classTemplateVanilla<char> st0;
90  * }
91  * }
92  * }
93  * @endcode
94  * would create two selection rules to select @c classVanilla and
95  * @c classTemplateVanilla<char>.
96  *
97  * A brief description of the properties that can be assigned to classes
98  * with the @c ROOT::Meta::Selection::ClassAttributes class.
99  * 1. @c kNonSplittable : Makes the class non splittable
100  *
101  * The class properties can be assigned via a traits mechanism. For example:
102  * @code
103  * [...]
104  * class classWithAttributes {};
105  * namespace ROOT {
106  * namespace Meta {
107  * namespace Selection {
108  * class classWithAttributes : ClassAttributes <kNonSplittable> {};
109  * }
110  * }
111  * }
112  * @endcode
113  * would create a selection rule which selects class @c classWithAttributes and
114  * assignes to it the property described by @c kNonSplittable. Multiple
115  * properties can be assigned to a single class with this syntax:
116  * @code
117  * [...]
118  * namespace ROOT {
119  * namespace Meta {
120  * namespace Selection {
121  * class classWithAttributes :
122  * ClassAttributes <kProperty1 + kProperty2 + ... + kPropertyN> {};
123  * }
124  * }
125  * }
126  * @endcode
127  *
128  * The @c ROOT::Meta::Selection syntax allows to alter the number of template
129  * parameters of a certain template class within the ROOT type system, TClass.
130  * Technically it allows to alter the way in which the "normalized name" (in
131  * other words, the "ROOT name") of the class is created. The key is the usage
132  * of the @c KeepFirstTemplateArguments traits class.
133  * It is possible to select the maximum number of template arguments considered
134  * if not different from the default. A concrete example can be more clear than
135  * a long explaination in this case:
136  * @code
137  * [...]
138  * template <class T, class U = int, int V = 3> class A {...};
139  * template <class T, class Alloc = myAllocator<T> > class myVector {...};
140  * A<char> a1;
141  * A<char, float> a2;
142  * myVector<float> v1;
143  * myVector<A<char>> v2;
144  *
145  * namespace ROOT {
146  * namespace Meta {
147  * namespace Selection {
148  * template <class T, class U = int, int V = 3> class A
149  * : KeepFirstTemplateArguments<1> {};
150  * A<double> a;
151  * template <class T, class Alloc = myAllocator<T> > class myVector
152  * : KeepFirstTemplateArguments<1> {};
153  * myVector<double> vd;
154  * }
155  * }
156  * }
157  * @endcode
158  *
159  * Consistently with what described above, all the instances of @c A and
160  * @c myvector will be selected. In addition, only the first template parameter
161  * will be kept.
162  * In absence of any @c KeepFirstTemplateArguments trait, the normalization
163  * would be:
164  * - @c A<char> &rarr; @c A<char,float,3>
165  * - @c A<char,float> &rarr; @c A<char,int,3>
166  * - @c myVector<float> &rarr; @c myVector<A<char,int,3>,myAllocator<A<char,int,3>>>
167  * - @c myVector<A<char>> &rarr; @c myVector<float,myAllocator<float>>
168  *
169  * Now, deciding to keep just one argument (@c KeepFirstTemplateArguments<1>):
170  * - @c A<char> &rarr; @c A<char,float>
171  * - @c A<char,float> &rarr; @c A<char>
172  * - @c myVector<float> &rarr; @c myVector<A<char>,myAllocator<A<char>>>
173  * - @c myVector<A<char>> &rarr; @c myVector<float,myAllocator<float>>
174  *
175  * And deciding to keep two arguments (@c KeepFirstTemplateArguments<2>):
176  * - @c A<char> &rarr; @c A<char,float>
177  * - @c A<char,float> &rarr; @c A<char,int>
178  * - @c myVector<float> &rarr; @c myVector<A<char,int>,myAllocator<A<char,int>>>
179  * - @c myVector<A<char>> &rarr; @c myVector<float,myAllocator<float>>
180  *
181  * A brief description of the properties that can be assigned to data members
182  * with the @c ROOT::Meta::Selection MemberAttributes class:
183  * 1. @c kTransient : the data member is transient, not persistified by the
184  * ROOT I/O.
185  * 2. @c kAutoSelected : the type of the data member is selected without the
186  * need of specifying its class explicitely.
187  *
188  * For example:
189  * @code
190  * [...]
191  * class classTransientMember {
192  * private:
193  * int transientMember;
194  * };
195  * class classAutoselected {};
196  * class classTestAutoselect {
197  * private:
198  * classAutoselected autoselected;
199  * };
200  *
201  * namespace ROOT {
202  * namespace Meta {
203  * namespace Selection {
204  * class classTestAutoselect {
205  * MemberAttributes<kAutoSelected> autoselected;
206  * };
207  * class classTransientMember {
208  * MemberAttributes<kTransient> transientMember;
209  * };
210  * }
211  * }
212  * }
213  * @endcode
214  * would lead to the creation of selection rules for @c classTransientMember
215  * specifying that @c transientMember is transient, @c classTestAutoselect and
216  * @c classAutoselected.
217  *
218  * Another trait class present in the @c ROOT::Meta::Selection is
219  * @c SelectNoInstance. If a template in the selection namespace inherits from
220  * this class, none of its instantiations will be automatically selected but
221  * all of the properties specified otherwise, like transient members or
222  * number of template arguments to keep, will be transmitted to all of the
223  * instantiations selected by other means.
224  * For example
225  * @code
226  * [...]
227  * template< class T, class BASE >
228  * class MyDataVector : KeepFirstTemplateArguments< 1 >, SelectNoInstance {
229  * MemberAttributes< kTransient + kAutoSelected > m_isMostDerived;
230  * MemberAttributes< kNonSplittable + kAutoSelected > m_isNonSplit;
231  * };
232  * [...]
233  * @endcode
234  **/
235 namespace ROOT {
236 namespace Internal {
237 
238 class DictSelectionReader : public clang::RecursiveASTVisitor<DictSelectionReader> {
239 public:
240  /// Take the selection rules as input (for consistency w/ other selector
241  /// interfaces)
242  DictSelectionReader(cling::Interpreter &interp, SelectionRules &, const clang::ASTContext &,
244 
245  /// Visit the entities that needs to be selected
246  bool VisitRecordDecl(clang::RecordDecl *);
247 
249  return true;
250  }
251 
252 private:
253 
254 
255  struct TemplateInfo { /// < Class to store the information about templates upon parsing
256  TemplateInfo(int argsToKeep): fArgsToKeep(argsToKeep) {};
258  int fArgsToKeep = -1;
259  std::unordered_set<std::string> fTransientMembers {};
260  std::unordered_set<std::string> fUnsplittableMembers {};
261  };
262 
263  inline bool
264  InSelectionNamespace(const clang::RecordDecl &,
265  const std::string &str =
266  ""); ///< Check if in the ROOT::Meta::Selection namespace
267  inline bool FirstPass(const clang::RecordDecl &); ///< First pass on the AST
268  inline bool SecondPass(const clang::RecordDecl &); ///< Second pass on the AST, using the information of the first one
269  inline void
270  ManageFields(const clang::RecordDecl &,
271  const std::string &,
273  bool); ///< Take care of the class fields
274  inline void
275  ManageBaseClasses(const clang::CXXRecordDecl &, const std::string &, bool &); ///< Take care of the class bases
276  template <class T>
277  inline unsigned int ExtractTemplateArgValue(
278  const T &,
279  const std::string &); ///< Extract the value of the template parameter
280  inline const clang::TemplateArgumentList *GetTmplArgList(
281  const clang::CXXRecordDecl &); ///< Get the template arguments list if any
282 
283  std::string PatternifyName(const std::string &className); ///< Transform instance name in pattern for selection
284  void GetPointeeType(std::string &typeName); ///< Get name of the pointee type
285 
286  SelectionRules &fSelectionRules; ///< The selection rules to be filled
287  std::set<const clang::RecordDecl *>
288  fSelectedRecordDecls; ///< The pointers of the selected RecordDecls
289  std::set<std::string>
290  fSpecialNames; ///< The names of the classes used for the selction syntax
291  llvm::StringMap<std::set<std::string> >
292  fAutoSelectedClassFieldNames; ///< Collect the autoselected classes
293  llvm::StringMap<std::set<std::string> >
294  fNoAutoSelectedClassFieldNames; ///< Collect the autoexcluded classes
295  std::unordered_map<std::string, TemplateInfo> fTemplateInfoMap; ///< List template name - properties map
296  llvm::StringMap<ClassSelectionRule>
297  fClassNameSelectionRuleMap; ///< Map of the already built sel rules
298  bool fIsFirstPass; ///< Keep trance of the number of passes through the AST
299  ROOT::TMetaUtils::TNormalizedCtxt &fNormCtxt; ///< The reference to the normalized context
300 };
301 }
302 }
303 
304 #endif
ROOT::Internal::DictSelectionReader::GetTmplArgList
const clang::TemplateArgumentList * GetTmplArgList(const clang::CXXRecordDecl &)
Get the template arguments list if any.
Definition: DictSelectionReader.cxx:102
ROOT::Internal::DictSelectionReader::ExtractTemplateArgValue
unsigned int ExtractTemplateArgValue(const T &, const std::string &)
Extract the value of the template parameter.
Definition: DictSelectionReader.cxx:121
ROOT::Internal::DictSelectionReader::GetPointeeType
void GetPointeeType(std::string &typeName)
Get name of the pointee type.
Definition: DictSelectionReader.cxx:411
ROOT::Internal::DictSelectionReader::TemplateInfo::fTransientMembers
std::unordered_set< std::string > fTransientMembers
Definition: DictSelectionReader.h:259
ROOT::Internal::DictSelectionReader::fTemplateInfoMap
std::unordered_map< std::string, TemplateInfo > fTemplateInfoMap
List template name - properties map.
Definition: DictSelectionReader.h:295
ROOT::Internal::DictSelectionReader::TemplateInfo::TemplateInfo
TemplateInfo()
Definition: DictSelectionReader.h:257
ROOT::Internal::DictSelectionReader::FirstPass
bool FirstPass(const clang::RecordDecl &)
First pass on the AST.
Definition: DictSelectionReader.cxx:250
ROOT::Internal::DictSelectionReader::PatternifyName
std::string PatternifyName(const std::string &className)
Transform instance name in pattern for selection.
Definition: DictSelectionReader.cxx:400
ROOT::Internal::DictSelectionReader::fIsFirstPass
bool fIsFirstPass
Keep trance of the number of passes through the AST.
Definition: DictSelectionReader.h:298
ROOT::Internal::DictSelectionReader::TemplateInfo::TemplateInfo
TemplateInfo(int argsToKeep)
< Class to store the information about templates upon parsing
Definition: DictSelectionReader.h:256
ROOT::Internal::DictSelectionReader::fNormCtxt
ROOT::TMetaUtils::TNormalizedCtxt & fNormCtxt
The reference to the normalized context.
Definition: DictSelectionReader.h:299
ROOT::Internal::DictSelectionReader
Definition: DictSelectionReader.h:238
ROOT::Internal::DictSelectionReader::ManageBaseClasses
void ManageBaseClasses(const clang::CXXRecordDecl &, const std::string &, bool &)
Take care of the class bases.
Definition: DictSelectionReader.cxx:217
ROOT::Internal::DictSelectionReader::fSelectionRules
SelectionRules & fSelectionRules
The selection rules to be filled.
Definition: DictSelectionReader.h:286
ROOT::Internal::DictSelectionReader::fSelectedRecordDecls
std::set< const clang::RecordDecl * > fSelectedRecordDecls
The pointers of the selected RecordDecls.
Definition: DictSelectionReader.h:288
ClassSelectionRule
Definition: ClassSelectionRule.h:34
ROOT::Internal::DictSelectionReader::fClassNameSelectionRuleMap
llvm::StringMap< ClassSelectionRule > fClassNameSelectionRuleMap
Map of the already built sel rules.
Definition: DictSelectionReader.h:297
ROOT::Internal::DictSelectionReader::VisitRecordDecl
bool VisitRecordDecl(clang::RecordDecl *)
Visit the entities that needs to be selected.
Definition: DictSelectionReader.cxx:385
ROOT::Internal::DictSelectionReader::fSpecialNames
std::set< std::string > fSpecialNames
The names of the classes used for the selction syntax.
Definition: DictSelectionReader.h:290
ROOT::TMetaUtils::TNormalizedCtxt
Definition: TClingUtils.h:138
ROOT::Internal::DictSelectionReader::TemplateInfo::fUnsplittableMembers
std::unordered_set< std::string > fUnsplittableMembers
Definition: DictSelectionReader.h:260
ROOT::Internal::DictSelectionReader::SecondPass
bool SecondPass(const clang::RecordDecl &)
Second pass on the AST, using the information of the first one.
Definition: DictSelectionReader.cxx:307
ROOT::Internal::DictSelectionReader::TemplateInfo::fArgsToKeep
int fArgsToKeep
Definition: DictSelectionReader.h:258
ROOT::Internal::DictSelectionReader::ManageFields
void ManageFields(const clang::RecordDecl &, const std::string &, ClassSelectionRule &, bool)
Take care of the class fields.
Definition: DictSelectionReader.cxx:152
clang
Definition: BaseSelectionRule.h:29
ROOT::Internal::DictSelectionReader::fNoAutoSelectedClassFieldNames
llvm::StringMap< std::set< std::string > > fNoAutoSelectedClassFieldNames
Collect the autoexcluded classes.
Definition: DictSelectionReader.h:294
ROOT::Internal::DictSelectionReader::fAutoSelectedClassFieldNames
llvm::StringMap< std::set< std::string > > fAutoSelectedClassFieldNames
Collect the autoselected classes.
Definition: DictSelectionReader.h:292
ROOT::Math::Chebyshev::T
double T(double x)
Definition: ChebyshevPol.h:34
ROOT::Internal::DictSelectionReader::shouldVisitTemplateInstantiations
bool shouldVisitTemplateInstantiations() const
Definition: DictSelectionReader.h:248
ROOT::Internal::DictSelectionReader::TemplateInfo
Definition: DictSelectionReader.h:255
ROOT::Internal::DictSelectionReader::InSelectionNamespace
bool InSelectionNamespace(const clang::RecordDecl &, const std::string &str="")
Check if in the ROOT::Meta::Selection namespace.
Definition: DictSelectionReader.cxx:63
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Internal::DictSelectionReader::DictSelectionReader
DictSelectionReader(cling::Interpreter &interp, SelectionRules &, const clang::ASTContext &, ROOT::TMetaUtils::TNormalizedCtxt &)
Take the selection rules as input (for consistency w/ other selector interfaces)
Definition: DictSelectionReader.cxx:22
SelectionRules
The class representing the collection of selection rules.
Definition: SelectionRules.h:92