source: src/AST/Pass.hpp @ 2bb4a01

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 2bb4a01 was f47f887, checked in by Thierry Delisle <tdelisle@…>, 5 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.