Changeset 04124c4 for src/AST/Pass.hpp
- Timestamp:
- May 10, 2019, 2:47:32 PM (4 years ago)
- Branches:
- arm-eh, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 37e3af4
- Parents:
- 7f3f63c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Pass.hpp
r7f3f63c r04124c4 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo 3 // 4 // The contents of this file are covered under the licence agreement in the 5 // file "LICENCE" distributed with Cforall. 6 // 7 // Pass.hpp -- 8 // 9 // Author : Thierry Delisle 10 // Created On : Thu May 09 15::37::05 2019 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 14 // 15 1 16 #pragma once 2 // IWYU pragma: private, include " Common/PassVisitor.h"17 // IWYU pragma: private, include "AST/Pass.hpp" 3 18 4 19 #include <functional> … … 6 21 #include <stack> 7 22 8 #include "Fwd.hpp" 9 #include "Node.hpp" 23 #include "AST/Fwd.hpp" 24 #include "AST/Node.hpp" 25 #include "AST/Decl.hpp" 26 #include "AST/Visitor.hpp" 27 28 #include "SymTab/Indexer.h" 10 29 11 30 // Private prelude header, needed for some of the magic tricks this class pulls off 12 #include " Pass.proto.hpp"31 #include "AST/Pass.proto.hpp" 13 32 14 33 namespace ast { … … 20 39 // 21 40 // Several additional features are available through inheritance 22 // | WithTypeSubstitution - provides polymorphic TypeSubstitution * env for the current expression 41 // | WithTypeSubstitution - provides polymorphic const TypeSubstitution * env for the 42 // current expression 23 43 // | WithStmtsToAdd - provides the ability to insert statements before or after the current 24 44 // statement by adding new statements into stmtsToAddBefore or 25 45 // stmtsToAddAfter respectively. 46 // | WithDeclsToAdd - provides the ability to insert declarations before or after the current 47 // declarations by adding new DeclStmt into declsToAddBefore or 48 // declsToAddAfter respectively. 26 49 // | WithShortCircuiting - provides the ability to skip visiting child nodes; set visit_children 27 50 // to false in pre{visit,visit} to skip visiting children … … 30 53 // automatically be restored to its previous value after the corresponding 31 54 // postvisit/postmutate teminates. 55 // | WithVisitorRef - provides an pointer to the templated visitor wrapper 56 // | WithIndexer - provides indexer functionality (i.e. up-to-date symbol table) 32 57 //------------------------------------------------------------------------------------------------- 33 58 template< typename pass_t > 34 59 class Pass final : public ast::Visitor { 35 60 public: 61 /// Forward any arguments to the pass constructor 62 /// Propagate 'this' if necessary 36 63 template< typename... Args > 37 64 Pass( Args &&... args) 38 : m_pass( std::forward<Args>( args )... )65 : pass( std::forward<Args>( args )... ) 39 66 { 40 67 // After the pass is constructed, check if it wants the have a pointer to the wrapping visitor 41 68 typedef Pass<pass_t> this_t; 42 this_t * const * visitor = __pass::visitor( m_pass, 0);69 this_t * const * visitor = __pass::visitor(pass, 0); 43 70 if(visitor) { 44 71 *const_cast<this_t **>( visitor ) = this; … … 48 75 virtual ~Pass() = default; 49 76 50 pass_t m_pass; 51 77 /// Storage for the actual pass 78 pass_t pass; 79 80 /// Visit function declarations 52 81 virtual DeclWithType * visit( const ObjectDecl * ) override final; 53 82 virtual DeclWithType * visit( const FunctionDecl * ) override final; … … 145 174 virtual TypeSubstitution * visit( const TypeSubstitution * ) override final; 146 175 176 friend void acceptAll( std::list< ptr<Decl> > & decls, Pass<pass_t>& visitor ); 147 177 private: 148 178 149 bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children( m_pass, 0); return ptr ? *ptr : true; }179 bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(pass, 0); return ptr ? *ptr : true; } 150 180 151 181 private: 182 /// Logic to call the accept and mutate the parent if needed, delegates call to accept 152 183 template<typename parent_t, typename child_t> 153 184 void maybe_accept(parent_t * & , typename parent_t::child_t *); 154 185 155 ast::Statement * call_accept( const ast::Statement* );156 ast::Expression * call_accept( const ast::Expression* );186 Stmt * call_accept( const Stmt * ); 187 Expr * call_accept( const Expr * ); 157 188 158 189 template< template <class> class container_t > 159 container_t< ast::ptr<ast::Statement> > call_accept( const container_t< ast::ptr<ast::Statement> > & );190 container_t< ptr<Stmt> > call_accept( const container_t< ptr<Stmt> > & ); 160 191 161 192 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 );193 container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container ); 163 194 164 195 private: 165 struct indexer_guard { 196 /// Internal RAII guard for indexer features 197 struct guard_indexer { 198 guard_indexer( Pass<pass_t> & pass ): pass( pass ) { __pass::indexer::enter(pass, 0); } 199 ~guard_indexer() { __pass::indexer::leave(pass, 0); } 166 200 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 201 }; 171 202 172 indexer_guard make_indexer_guard() { return { *this }; }173 174 private: 175 struct scope_guard {203 /// Internal RAII guard for scope features 204 struct guard_scope { 205 guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass, 0); } 206 ~guard_scope() { __pass::scope::leave(pass, 0); } 176 207 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 208 }; 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 187 template<typename pass_t, typename T> 188 void 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 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 209 }; 210 211 template<typename pass_t> 212 void acceptAll( std::list< ptr<Decl> >, Pass<pass_t>& visitor ); 213 214 //------------------------------------------------------------------------------------------------- 195 215 // PASS ACCESSORIES 196 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 197 198 // Keep track of the type substitution 199 struct WithConstTypeSubstitution { 200 const ast::TypeSubstitution * env = nullptr; 201 }; 216 //------------------------------------------------------------------------------------------------- 202 217 203 218 template<typename T> 204 219 using std_list = std::list<T>; 205 220 206 // Used if visitor requires added statements before or after the current node. 207 // The Pass template handles what *before* and *after* means automatically 221 /// Keep track of the polymorphic const TypeSubstitution * env for the current expression 222 struct WithConstTypeSubstitution { 223 const TypeSubstitution * env = nullptr; 224 }; 225 226 /// Used if visitor requires added statements before or after the current node. 227 /// The Pass template handles what *before* and *after* means automatically 208 228 template< template<class> class container_t = std_list > 209 229 struct 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 automatically230 container_t< ptr<Stmt> > stmtsToAddBefore; 231 container_t< ptr<Stmt> > stmtsToAddAfter; 232 }; 233 234 /// Used if visitor requires added declarations before or after the current node. 235 /// The Pass template handles what *before* and *after* means automatically 216 236 template< template<class> class container_t = std_list > 217 237 struct 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 238 container_t< ptr<Decl> > declsToAddBefore; 239 container_t< ptr<Decl> > declsToAddAfter; 240 }; 241 242 /// Use if visitation should stop at certain levels 243 /// set visit_children false of all child nodes should be ignored 228 244 struct WithShortCircuiting { 229 245 __pass::bool_ref visit_children; 230 246 }; 231 247 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 248 /// Used to restore values/functions/etc. when the Pass finishes visiting this node 249 class WithGuards { 250 __pass::at_cleanup_t at_cleanup; 251 252 public: 253 /// When this node is finished being visited, restore the value of a variable 254 template< typename T > 255 void GuardValue( T& val ) { 256 at_cleanup( [ val ]( void * newVal ) { 257 * static_cast< T * >( newVal ) = val; 258 }, static_cast< void * >( & val ) ); 259 } 260 261 /// On the object, all beginScope now and endScope when the current node is finished being visited 262 template< typename T > 263 void GuardScope( T& val ) { 264 val.beginScope(); 265 at_cleanup( []( void * val ) { 266 static_cast< T * >( val )->endScope(); 267 }, static_cast< void * >( & val ) ); 268 } 269 270 /// When this node is finished being visited, call a function 271 template< typename Func > 272 void GuardAction( Func func ) { 273 at_cleanup( [func](void *) { func(); }, nullptr ); 274 } 275 }; 276 277 /// Used to get a pointer to the pass with its wrapped type 278 template<typename pass_t> 279 struct WithVisitorRef { 280 Pass<pass_t> * const visitor = nullptr; 281 }; 282 283 /// Use when the templated visitor should update the indexer 271 284 struct WithIndexer { 272 285 SymTab::Indexer indexer;
Note: See TracChangeset
for help on using the changeset viewer.