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