Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
Scanner.h
Go to the documentation of this file.
1 // @(#)root/utils/src:$Id$
2 // Author: Philippe Canal November 2011 ;
3 // 16/04/2010 and Velislava Spasova.
4 // originated from Zdenek Culik
5 
6 
7 /*************************************************************************
8  * Copyright (C) 1995-2011, Rene Brun and Fons Rademakers. *
9  * All rights reserved. *
10  * *
11  * For the licensing terms see $ROOTSYS/LICENSE. *
12  * For the list of contributors see $ROOTSYS/README/rootcint. *
13  *************************************************************************/
14 
15 #ifndef ROOT__RSCANNER_H__
16 #define ROOT__RSCANNER_H__
17 
18 #include <stack>
19 
20 #include "clang/AST/AST.h"
21 #include "clang/AST/ASTContext.h"
22 #include "clang/AST/DeclGroup.h"
23 #include "clang/AST/DeclFriend.h"
24 #include "clang/AST/Type.h"
25 #include "clang/AST/RecursiveASTVisitor.h"
26 
27 #include "llvm/IR/Module.h"
28 
29 #include "TClingUtils.h"
30 
31 namespace clang {
32  class ClassTemplatePartialSpecializationDecl;
33  class ClassTemplateDecl;
34  class RecordDecl;
35  class Stmt;
36 }
37 
38 namespace cling {
39  class Interpreter;
40 }
41 
42 class SelectionRules;
43 class BaseSelectionRule;
44 class ClassSelectionRule;
45 
46 class RScanner: public clang::RecursiveASTVisitor<RScanner>
47 {
48 
49  bool shouldVisitDecl(clang::NamedDecl *D);
50 
51 public:
52  class AnnotatedNamespaceDecl {
53  public:
54  AnnotatedNamespaceDecl(clang::NamespaceDecl *decl, long index, bool rRequestOnlyTClass) :
55  fDecl(decl), fRuleIndex(index), fRequestOnlyTClass(rRequestOnlyTClass){}
56  AnnotatedNamespaceDecl() { /* Nothing to do we do not own the pointer; */}
57  bool RequestOnlyTClass() const { return fRequestOnlyTClass; }
58  const clang::NamespaceDecl* GetNamespaceDecl() const { return fDecl; }
59  operator clang::NamespaceDecl const *() const { return fDecl; }
60  bool operator<(const AnnotatedNamespaceDecl& right) { return fRuleIndex < right.fRuleIndex; }
61  private:
62  const clang::NamespaceDecl *fDecl;
63  long fRuleIndex;
64  bool fRequestOnlyTClass;
65  };
66 
67  typedef std::vector<AnnotatedNamespaceDecl> NamespaceColl_t;
68  typedef std::vector<ROOT::TMetaUtils::AnnotatedRecordDecl> ClassColl_t;
69  typedef std::vector<const clang::TypedefNameDecl*> TypedefColl_t;
70  typedef std::vector<const clang::FunctionDecl*> FunctionColl_t;
71  typedef std::vector<const clang::VarDecl*> VariableColl_t;
72  typedef std::vector<const clang::EnumDecl*> EnumColl_t;
73  typedef void (*DeclCallback)(const clang::RecordDecl*);
74  typedef std::map<const clang::Decl*,const BaseSelectionRule*> DeclsSelRulesMap_t;
75 
76  enum class EScanType : char {kNormal, kTwoPasses, kOnePCM};
77 
78  RScanner (SelectionRules &rules,
79  EScanType stype,
80  const cling::Interpreter &interpret,
81  ROOT::TMetaUtils::TNormalizedCtxt &normCtxt,
82  unsigned int verbose = 0);
83 
84  // Configure the vistitor to also visit template instantiation.
85  bool shouldVisitTemplateInstantiations() const { return true; }
86 
87  // Don't descend into function bodies.
88  bool TraverseStmt(clang::Stmt*) { return true; }
89 
90  // Don't descend into templates partial specialization (but only instances thereof).
91  bool TraverseClassTemplatePartialSpecializationDecl(clang::ClassTemplatePartialSpecializationDecl*) { return true; }
92 
93  bool VisitEnumDecl(clang::EnumDecl* D); //Visitor for every EnumDecl i.e. enumeration node in the AST
94  bool VisitFieldDecl(clang::FieldDecl* D); //Visitor for e field inside a class
95  bool VisitFunctionDecl(clang::FunctionDecl* D); //Visitor for every FunctionDecl i.e. function node in the AST
96  bool VisitNamespaceDecl(clang::NamespaceDecl* D); // Visitor for every RecordDecl i.e. class node in the AST
97  bool VisitRecordDecl(clang::RecordDecl* D); // Visitor for every RecordDecl i.e. class node in the AST
98  bool VisitTypedefNameDecl(clang::TypedefNameDecl* D); // Visitor for every TypedefNameDecl i.e. class node in the AST
99  bool VisitVarDecl(clang::VarDecl* D); //Visitor for every VarDecl i.e. variable node in the AST
100 
101  bool TreatRecordDeclOrTypedefNameDecl(clang::TypeDecl* typeDecl); //Function called by VisitTypedefNameDecl and VisitRecordDecl
102  void AddDelayedAnnotatedRecordDecls();
103 
104  bool TraverseDeclContextHelper(clang::DeclContext *DC); // Here is the code magic :) - every Decl
105  // according to its type is processed by the corresponding Visitor method
106 
107  // Set a callback to record which are declared.
108  DeclCallback SetRecordDeclCallback(DeclCallback callback);
109 
110  // Main interface of this class.
111  void Scan(const clang::ASTContext &C);
112 
113  // Utility routines. Most belongs in TMetaUtils and should be shared with rootcling.cxx
114  bool GetDeclName(clang::Decl* D, std::string& name) const;
115  static bool GetDeclQualName(const clang::Decl* D, std::string& qual_name);
116  bool GetFunctionPrototype(clang::Decl* D, std::string& prototype) const;
117 
118  static const char* fgClangDeclKey; // property key used for CLang declaration objects
119  static const char* fgClangFuncKey; // property key for function (demangled) names
120 
121  const DeclsSelRulesMap_t& GetDeclsSelRulesMap() const {return fDeclSelRuleMap;};
122 
123  // public for now, the list of selected classes.
124  ClassColl_t fSelectedClasses;
125  NamespaceColl_t fSelectedNamespaces;
126  TypedefColl_t fSelectedTypedefs;
127  FunctionColl_t fSelectedFunctions;
128  VariableColl_t fSelectedVariables;
129  EnumColl_t fSelectedEnums;
130 
131  struct DelayedAnnotatedRecordDeclInfo {
132  const ClassSelectionRule *fSelected;
133  const clang::ClassTemplateSpecializationDecl *fDecl;
134  const clang::TypedefNameDecl* fTypedefNameDecl;
135  };
136  std::vector<DelayedAnnotatedRecordDeclInfo> fDelayedAnnotatedRecordDecls;
137 
138  virtual ~RScanner ();
139 
140 
141 
142 private:
143 
144  int AddAnnotatedRecordDecl(const ClassSelectionRule*,
145  const clang::Type*,
146  const clang::RecordDecl*,
147  const std::string&,
148  const clang::TypedefNameDecl*,
149  unsigned int indexOffset=0);
150  std::string ConvTemplateArguments(const clang::TemplateArgumentList& list) const;
151  std::string ConvTemplateName(clang::TemplateName& N) const;
152  std::string ConvTemplateParameterList(clang::TemplateParameterList* list) const;
153  std::string ConvTemplateParams(clang::TemplateDecl* D) const;
154  void DeclInfo(clang::Decl* D) const;
155  std::string ExprToStr(clang::Expr* expr) const;
156  std::string FuncParameterList(clang::FunctionDecl* D) const;
157  std::string FuncParameters(clang::FunctionDecl* D) const;
158  std::string GetEnumName(clang::EnumDecl* D) const;
159  std::string GetLocation(clang::Decl* D) const;
160  std::string GetName(clang::Decl* D) const;
161  std::string GetSrcLocation(clang::SourceLocation L) const;
162  unsigned int FuncModifiers(clang::FunctionDecl* D) const;
163  unsigned int fVerboseLevel;
164  unsigned int VarModifiers(clang::VarDecl* D) const;
165  unsigned int Visibility(clang::Decl* D) const;
166  unsigned int VisibilityModifiers(clang::AccessSpecifier access) const;
167  void ShowError(const std::string &msg, const std::string &location = "") const;
168  void ShowInfo(const std::string &msg, const std::string &location = "") const;
169  void ShowTemplateInfo(const std::string &msg, const std::string &location = "") const;
170  void ShowWarning(const std::string &msg, const std::string &location = "") const;
171  static std::map <clang::Decl*, std::string> fgAnonymousClassMap;
172  static std::map <clang::Decl*, std::string> fgAnonymousEnumMap;
173  void UnexpectedDecl(clang::Decl* D,const std::string &txt = "") const;
174  void UnimplementedDecl(clang::Decl* D,const std::string &txt = "");
175  void UnimportantDecl(clang::Decl* D,const std::string &txt = "") const;
176  void UnknownDecl(clang::Decl* D, const std::string &txt = "") const;
177  void UnknownType(clang::QualType qual_type) const;
178  void UnsupportedDecl(clang::Decl* D,const std::string &txt = "") const;
179  void UnsupportedType(clang::QualType qual_type) const;
180 
181  const clang::SourceManager* fSourceManager;
182  const cling::Interpreter &fInterpreter;
183  static const int fgDeclLast = clang::Decl::Var;
184  static const int fgTypeLast = clang::Type::TemplateTypeParm;
185  bool fDeclTable [ fgDeclLast+1 ];
186  clang::Decl * fLastDecl;
187  DeclCallback fRecordDeclCallback;
188  bool fTypeTable [ fgTypeLast+1 ];
189  static int fgAnonymousClassCounter;
190  static int fgAnonymousEnumCounter;
191  static int fgBadClassCounter;
192  ROOT::TMetaUtils::TNormalizedCtxt &fNormCtxt;
193  SelectionRules &fSelectionRules;
194  std::set<clang::RecordDecl*> fselectedRecordDecls; // Set for O(logN)
195  EScanType fScanType; // Differentiate among different kind of scans
196  bool fFirstPass; // This flag allows to run twice, for example in presence of dict selection and recursive template list manipulations.
197  DeclsSelRulesMap_t fDeclSelRuleMap; // Map decls to selection rules which selected them
198 
199 };
200 
201 #endif /* ROOT__RSCANNER_H__ */