// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // GcTracer.h -- // // Author : Aaron B. Moss // Created On : Thu Mar 15 14:47:00 2018 // Last Modified By : Aaron B. Moss // Last Modified On : Thu Mar 15 14:47:00 2018 // Update Count : 1 // #pragma once #include #include "BaseSyntaxNode.h" #include "Expression.h" #include "Label.h" #include "Type.h" #include "Common/GC.h" #include "Common/PassVisitor.h" class Expression; /// Implements `trace` method for syntax nodes class GcTracer final : public WithShortCircuiting, public WithVisitorRef { const GC& gc; public: GcTracer( const GC& gc ) : gc(gc) {} // mark node and children void previsit( BaseSyntaxNode * node ) { // skip tree if already seen if ( node->mark == gc.mark ) { visit_children = false; return; } // mark node node->mark = gc.mark; } // add visits left out by PassVisitor void postvisit( Constant* con ) { maybeAccept( con->get_type(), *visitor ); } void postvisit( AggregateDecl* decl ) { acceptAll( decl->attributes, *visitor ); } void postvisit( DeclarationWithType* decl ) { maybeAccept( decl->asmName, *visitor ); } private: void visit( InferredParams& inferParams ) { for ( auto& entry : inferParams ) { maybeAccept( entry.second.actualType, *visitor ); maybeAccept( entry.second.formalType, *visitor ); maybeAccept( entry.second.expr, *visitor ); visit( *entry.second.inferParams ); } } public: void postvisit( Expression* expr ) { maybeAccept( expr->env, *visitor ); visit( expr->inferParams ); } void postvisit( UniqueExpr* expr ) { postvisit( static_cast(expr) ); maybeAccept( expr->object, *visitor ); maybeAccept( expr->var, *visitor ); } void postvisit( UntypedExpr* expr ) { postvisit( static_cast(expr) ); maybeAccept( expr->function, *visitor ); } void postvisit( VariableExpr* expr ) { postvisit( static_cast(expr) ); maybeAccept( expr->var, *visitor ); // not in PassVisitor because it causes cycle } private: void visit( Label& lbl ) { acceptAll( lbl.get_attributes(), *visitor ); maybeAccept( lbl.get_statement(), *visitor ); // xxx - not sure this is needed... } public: void postvisit( Statement* stmt ) { for ( Label& l : stmt->labels ) { visit( l ); } } void postvisit( Type* type ) { acceptAll( type->attributes, *visitor ); } void postvisit( PointerType* type ) { postvisit( static_cast(type) ); maybeAccept( type->dimension, *visitor ); } }; /// Traces entire translation unit recursively static inline const GC& operator<< ( const GC& gc, const std::list& translationUnit ) { PassVisitor tracer{ gc }; acceptAll( const_cast&>( translationUnit ), tracer ); return gc; } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //