source: src/SynTree/GcTracer.h @ 8a1289f

new-envwith_gc
Last change on this file since 8a1289f was 3ef35bd, checked in by Aaron Moss <a3moss@…>, 6 years ago

Tractable tests all pass in GC branch; added tracing for BranchStmt?

  • Property mode set to 100644
File size: 3.9 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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// GcTracer.h --
8//
9// Author           : Aaron B. Moss
10// Created On       : Thu Mar 15 14:47:00 2018
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Thu Mar 15 14:47:00 2018
13// Update Count     : 1
14//
15
16#pragma once
17
18#include <list>
19
20#include "BaseSyntaxNode.h"
21#include "Expression.h"
22#include "Label.h"
23#include "Type.h"
24
25#include "Common/GC.h"
26#include "Common/PassVisitor.h"
27
28class Expression;
29
30/// Implements `trace` method for syntax nodes
31class GcTracer final : public WithShortCircuiting, public WithVisitorRef<GcTracer> {
32        const GC& gc;
33
34public:
35        GcTracer( const GC& gc ) : gc(gc) {}
36
37        // mark node and children
38
39        void previsit( BaseSyntaxNode * node ) {
40                // skip tree if already seen
41                if ( node->mark == gc.mark ) {
42                        visit_children = false;
43                        return;
44                }
45
46                // mark node
47                node->mark = gc.mark;
48        }
49
50        // add visits left out by PassVisitor
51
52        void postvisit( Constant* con ) {
53                maybeAccept( con->get_type(), *visitor );
54        }
55
56        void postvisit( AggregateDecl* decl ) {
57                acceptAll( decl->attributes, *visitor );
58        }
59
60        void postvisit( DeclarationWithType* decl ) {
61                maybeAccept( decl->asmName, *visitor );
62        }
63
64private:
65        void visit( InferredParams& inferParams ) {
66                for ( auto& entry : inferParams ) {
67                        maybeAccept( entry.second.actualType, *visitor );
68                        maybeAccept( entry.second.formalType, *visitor );
69                        maybeAccept( entry.second.expr, *visitor );
70                        visit( *entry.second.inferParams );
71                }
72        }
73
74public:
75        void postvisit( Expression* expr ) {
76                maybeAccept( expr->env, *visitor );
77                visit( expr->inferParams );
78        }
79
80        void postvisit( OffsetofExpr* expr ) {
81                postvisit( static_cast<Expression*>(expr) );
82                maybeAccept( expr->member, *visitor );
83        }
84
85        void postvisit( UniqueExpr* expr ) {
86                postvisit( static_cast<Expression*>(expr) );
87                maybeAccept( expr->object, *visitor );
88                maybeAccept( expr->var, *visitor );
89        }
90
91        void postvisit( UntypedExpr* expr ) {
92                postvisit( static_cast<Expression*>(expr) );
93                maybeAccept( expr->function, *visitor );
94        }
95
96        void postvisit( VariableExpr* expr ) {
97                postvisit( static_cast<Expression*>(expr) );
98                maybeAccept( expr->var, *visitor );  // not in PassVisitor because it causes cycle
99        }
100
101private:
102        void visit( Label& lbl ) {
103                acceptAll( lbl.get_attributes(), *visitor );
104                // maybeAccept( lbl.get_statement(), *visitor );  // introduces infinite loop in tracer
105        }
106
107public:
108        void postvisit( Statement* stmt ) {
109                for ( Label& l : stmt->labels ) {
110                        visit( l );
111                }
112        }
113
114        void postvisit( BranchStmt* stmt ) {
115                postvisit( static_cast<Statement*>(stmt) );
116                visit( stmt->target );
117                maybeAccept( stmt->computedTarget, *visitor );
118        }
119
120        void postvisit( Type* type ) {
121                acceptAll( type->attributes, *visitor );
122        }
123
124        void postvisit( EnumInstType* type ) {
125                postvisit( static_cast<Type*>(type) );
126                maybeAccept( type->baseEnum, *visitor );
127        }
128
129        void postvisit( PointerType* type ) {
130                postvisit( static_cast<Type*>(type) );
131                maybeAccept( type->dimension, *visitor );
132        }
133
134        void postvisit( StructInstType* type ) {
135                postvisit( static_cast<Type*>(type) );
136                maybeAccept( type->baseStruct, *visitor );
137        }
138
139        void postvisit( TraitInstType* type ) {
140                postvisit( static_cast<Type*>(type) );
141                maybeAccept( type->baseTrait, *visitor );
142        }
143
144        void postvisit( TypeInstType* type ) {
145                postvisit( static_cast<Type*>(type) );
146                maybeAccept( type->baseType, *visitor );
147        }
148
149        void postvisit( UnionInstType* type ) {
150                postvisit( static_cast<Type*>(type) );
151                maybeAccept( type->baseUnion, *visitor );
152        }
153};
154
155/// Traces entire translation unit recursively
156static inline const GC& operator<< ( const GC& gc, const std::list<Declaration*>& translationUnit ) {
157        PassVisitor<GcTracer> tracer{ gc };
158        acceptAll( const_cast<std::list<Declaration*>&>( translationUnit ), tracer );
159        return gc;
160}
161
162// Local Variables: //
163// tab-width: 4 //
164// mode: c++ //
165// compile-command: "make install" //
166// End: //
Note: See TracBrowser for help on using the repository browser.