source: src/AST/Pass.hpp@ 9131e54

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 9131e54 was f47f887, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

First draft of Pass.hpp and some updates to node.hpp

  • Property mode set to 100644
File size: 13.7 KB
Line 
1#pragma once
2// IWYU pragma: private, include "Common/PassVisitor.h"
3
4#include <functional>
5#include <list>
6#include <stack>
7
8#include "Fwd.hpp"
9#include "Node.hpp"
10
11// Private prelude header, needed for some of the magic tricks this class pulls off
12#include "Pass.proto.hpp"
13
14namespace ast {
15//-------------------------------------------------------------------------------------------------
16// Templated visitor type
17// To use declare a Pass< YOUR VISITOR TYPE >
18// The visitor type should specify the previsit/postvisit for types that are desired.
19// Note: previsit/postvisit must be **public** members
20//
21// Several additional features are available through inheritance
22// | WithTypeSubstitution - provides polymorphic TypeSubstitution * env for the current expression
23// | WithStmtsToAdd - provides the ability to insert statements before or after the current
24// statement by adding new statements into stmtsToAddBefore or
25// stmtsToAddAfter respectively.
26// | WithShortCircuiting - provides the ability to skip visiting child nodes; set visit_children
27// to false in pre{visit,visit} to skip visiting children
28// | WithGuards - provides the ability to save/restore data like a LIFO stack; to save,
29// call GuardValue with the variable to save, the variable will
30// automatically be restored to its previous value after the corresponding
31// postvisit/postmutate teminates.
32//-------------------------------------------------------------------------------------------------
33template< typename pass_t >
34class Pass final : public ast::Visitor {
35public:
36 template< typename... Args >
37 Pass( Args &&... args)
38 : m_pass( std::forward<Args>( args )... )
39 {
40 // After the pass is constructed, check if it wants the have a pointer to the wrapping visitor
41 typedef Pass<pass_t> this_t;
42 this_t * const * visitor = __pass::visitor(m_pass, 0);
43 if(visitor) {
44 *const_cast<this_t **>( visitor ) = this;
45 }
46 }
47
48 virtual ~Pass() = default;
49
50 pass_t m_pass;
51
52 virtual DeclWithType * visit( const ObjectDecl * ) override final;
53 virtual DeclWithType * visit( const FunctionDecl * ) override final;
54 virtual Decl * visit( const StructDecl * ) override final;
55 virtual Decl * visit( const UnionDecl * ) override final;
56 virtual Decl * visit( const EnumDecl * ) override final;
57 virtual Decl * visit( const TraitDecl * ) override final;
58 virtual Decl * visit( const TypeDecl * ) override final;
59 virtual Decl * visit( const TypedefDecl * ) override final;
60 virtual AsmDecl * visit( const AsmDecl * ) override final;
61 virtual StaticAssertDecl * visit( const StaticAssertDecl * ) override final;
62 virtual CompoundStmt * visit( const CompoundStmt * ) override final;
63 virtual Stmt * visit( const ExprStmt * ) override final;
64 virtual Stmt * visit( const AsmStmt * ) override final;
65 virtual Stmt * visit( const DirectiveStmt * ) override final;
66 virtual Stmt * visit( const IfStmt * ) override final;
67 virtual Stmt * visit( const WhileStmt * ) override final;
68 virtual Stmt * visit( const ForStmt * ) override final;
69 virtual Stmt * visit( const SwitchStmt * ) override final;
70 virtual Stmt * visit( const CaseStmt * ) override final;
71 virtual Stmt * visit( const BranchStmt * ) override final;
72 virtual Stmt * visit( const ReturnStmt * ) override final;
73 virtual Stmt * visit( const ThrowStmt * ) override final;
74 virtual Stmt * visit( const TryStmt * ) override final;
75 virtual Stmt * visit( const CatchStmt * ) override final;
76 virtual Stmt * visit( const FinallyStmt * ) override final;
77 virtual Stmt * visit( const WaitForStmt * ) override final;
78 virtual Stmt * visit( const WithStmt * ) override final;
79 virtual NullStmt * visit( const NullStmt * ) override final;
80 virtual Stmt * visit( const DeclStmt * ) override final;
81 virtual Stmt * visit( const ImplicitCtorDtorStmt * ) override final;
82 virtual Expr * visit( const ApplicationExpr * ) override final;
83 virtual Expr * visit( const UntypedExpr * ) override final;
84 virtual Expr * visit( const NameExpr * ) override final;
85 virtual Expr * visit( const AddressExpr * ) override final;
86 virtual Expr * visit( const LabelAddressExpr * ) override final;
87 virtual Expr * visit( const CastExpr * ) override final;
88 virtual Expr * visit( const KeywordCastExpr * ) override final;
89 virtual Expr * visit( const VirtualCastExpr * ) override final;
90 virtual Expr * visit( const UntypedMemberExpr * ) override final;
91 virtual Expr * visit( const MemberExpr * ) override final;
92 virtual Expr * visit( const VariableExpr * ) override final;
93 virtual Expr * visit( const ConstantExpr * ) override final;
94 virtual Expr * visit( const SizeofExpr * ) override final;
95 virtual Expr * visit( const AlignofExpr * ) override final;
96 virtual Expr * visit( const UntypedOffsetofExpr * ) override final;
97 virtual Expr * visit( const OffsetofExpr * ) override final;
98 virtual Expr * visit( const OffsetPackExpr * ) override final;
99 virtual Expr * visit( const AttrExpr * ) override final;
100 virtual Expr * visit( const LogicalExpr * ) override final;
101 virtual Expr * visit( const ConditionalExpr * ) override final;
102 virtual Expr * visit( const CommaExpr * ) override final;
103 virtual Expr * visit( const TypeExpr * ) override final;
104 virtual Expr * visit( const AsmExpr * ) override final;
105 virtual Expr * visit( const ImplicitCopyCtorExpr * ) override final;
106 virtual Expr * visit( const ConstructorExpr * ) override final;
107 virtual Expr * visit( const CompoundLiteralExpr * ) override final;
108 virtual Expr * visit( const RangeExpr * ) override final;
109 virtual Expr * visit( const UntypedTupleExpr * ) override final;
110 virtual Expr * visit( const TupleExpr * ) override final;
111 virtual Expr * visit( const TupleIndexExpr * ) override final;
112 virtual Expr * visit( const TupleAssignExpr * ) override final;
113 virtual Expr * visit( const StmtExpr * ) override final;
114 virtual Expr * visit( const UniqueExpr * ) override final;
115 virtual Expr * visit( const UntypedInitExpr * ) override final;
116 virtual Expr * visit( const InitExpr * ) override final;
117 virtual Expr * visit( const DeletedExpr * ) override final;
118 virtual Expr * visit( const DefaultArgExpr * ) override final;
119 virtual Expr * visit( const GenericExpr * ) override final;
120 virtual Type * visit( const VoidType * ) override final;
121 virtual Type * visit( const BasicType * ) override final;
122 virtual Type * visit( const PointerType * ) override final;
123 virtual Type * visit( const ArrayType * ) override final;
124 virtual Type * visit( const ReferenceType * ) override final;
125 virtual Type * visit( const QualifiedType * ) override final;
126 virtual Type * visit( const FunctionType * ) override final;
127 virtual Type * visit( const StructInstType * ) override final;
128 virtual Type * visit( const UnionInstType * ) override final;
129 virtual Type * visit( const EnumInstType * ) override final;
130 virtual Type * visit( const TraitInstType * ) override final;
131 virtual Type * visit( const TypeInstType * ) override final;
132 virtual Type * visit( const TupleType * ) override final;
133 virtual Type * visit( const TypeofType * ) override final;
134 virtual Type * visit( const AttrType * ) override final;
135 virtual Type * visit( const VarArgsType * ) override final;
136 virtual Type * visit( const ZeroType * ) override final;
137 virtual Type * visit( const OneType * ) override final;
138 virtual Type * visit( const GlobalScopeType * ) override final;
139 virtual Designation * visit( const Designation * ) override final;
140 virtual Init * visit( const SingleInit * ) override final;
141 virtual Init * visit( const ListInit * ) override final;
142 virtual Init * visit( const ConstructorInit * ) override final;
143 virtual Constant * visit( const Constant * ) override final;
144 virtual Attribute * visit( const Attribute * ) override final;
145 virtual TypeSubstitution * visit( const TypeSubstitution * ) override final;
146
147private:
148
149 bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(m_pass, 0); return ptr ? *ptr : true; }
150
151private:
152 template<typename parent_t, typename child_t>
153 void maybe_accept(parent_t * & , typename parent_t::child_t *);
154
155 ast::Statement * call_accept( const ast::Statement * );
156 ast::Expression * call_accept( const ast::Expression * );
157
158 template< template <class> class container_t >
159 container_t< ast::ptr<ast::Statement> > call_accept( const container_t< ast::ptr<ast::Statement> > & );
160
161 template< template <class> class container_t, typename node_t >
162 container_t< ast::ptr<node_t> > call_accept( const container_t< ast::ptr<node_t> > & container );
163
164private:
165 struct indexer_guard {
166 Pass<pass_t> & pass;
167
168 indexer_guard( Pass<pass_t> & pass ) : pass( pass ) { __pass::indexer::enter(pass, 0); }
169 ~indexer_guard() { __pass::indexer::leave(pass, 0); }
170 };
171
172 indexer_guard make_indexer_guard() { return { *this }; }
173
174private:
175 struct scope_guard {
176 Pass<pass_t> & pass;
177
178 scope_guard( Pass<pass_t> & pass ) : pass( pass ) { __pass::scope::enter(pass, 0); }
179 ~scope_guard() { __pass::scope::leave(pass, 0); }
180 };
181
182 scope_guard make_scope_guard() { return { *this }; }
183};
184
185//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
186// Guard value : RAII type to restore a value when the Pass finishes visiting this node
187template<typename pass_t, typename T>
188void GuardValue( pass_t * pass, T& val ) {
189 pass->at_cleanup( [ val ]( void * newVal ) {
190 * static_cast< T * >( newVal ) = val;
191 }, static_cast< void * >( & val ) );
192}
193
194//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
195// PASS ACCESSORIES
196//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
197
198// Keep track of the type substitution
199struct WithConstTypeSubstitution {
200 const ast::TypeSubstitution * env = nullptr;
201};
202
203template<typename T>
204using std_list = std::list<T>;
205
206// Used if visitor requires added statements before or after the current node.
207// The Pass template handles what *before* and *after* means automatically
208template< template<class> class container_t = std_list >
209struct WithStmtsToAdd {
210 container_t< ast::ptr< ast::Statement > > stmtsToAddBefore;
211 container_t< ast::ptr< ast::Statement > > stmtsToAddAfter;
212};
213
214// Used if visitor requires added declarations before or after the current node.
215// The Pass template handles what *before* and *after* means automatically
216template< template<class> class container_t = std_list >
217struct WithDeclsToAdd {
218 ~WithDeclsToAdd() {
219 assert( declsToAddBefore.empty() );
220 }
221
222 container_t< ast::ptr< ast::Declaration > > declsToAddBefore;
223 container_t< ast::ptr< ast::Declaration > > declsToAddAfter;
224};
225
226// Use if visitation should stop at certain levels
227// set visit_children false of all child nodes should be ignored
228struct WithShortCircuiting {
229 __pass::bool_ref visit_children;
230};
231
232// class WithGuards {
233// protected:
234// WithGuards() = default;
235// ~WithGuards() = default;
236
237// public:
238// at_cleanup_t at_cleanup;
239
240// template< typename T >
241// void GuardValue( T& val ) {
242// at_cleanup( [ val ]( void * newVal ) {
243// * static_cast< T * >( newVal ) = val;
244// }, static_cast< void * >( & val ) );
245// }
246
247// template< typename T >
248// void GuardScope( T& val ) {
249// val.beginScope();
250// at_cleanup( []( void * val ) {
251// static_cast< T * >( val )->endScope();
252// }, static_cast< void * >( & val ) );
253// }
254
255// template< typename Func >
256// void GuardAction( Func func ) {
257// at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr );
258// }
259// };
260
261// template<typename pass_type>
262// class WithVisitorRef {
263// protected:
264// WithVisitorRef() {}
265// ~WithVisitorRef() {}
266
267// public:
268// PassVisitor<pass_type> * const visitor = nullptr;
269// };
270
271struct WithIndexer {
272 SymTab::Indexer indexer;
273};
274}
Note: See TracBrowser for help on using the repository browser.