// // 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. // // TopLvalue.cc -- Check and force that lvalue is only at the top of types. // // Author : Andrew Beach // Created On : Wed Jul 31 15:49:00 2019 // Last Modified By : Andrew Beach // Last Modified On : Wed Aug 7 15:36:00 2019 // Update Count : 0 // #include #include "Common/PassVisitor.h" namespace { class TopLvalue : public WithGuards { bool inType = false; public: void previsit( const BaseSyntaxNode * ) { if ( inType ) { GuardValue( inType ); inType = false; } } void previsit( const Type * type ) { if ( inType ) { assert( !type->get_lvalue() ); } else { GuardValue( inType ); inType = true; } } }; class ClearLvalue : public WithGuards { bool inType = false; public: void previsit( BaseSyntaxNode * ) { if ( inType ) { GuardValue( inType ); inType = false; } } void previsit( Type * type ) { if ( !inType ) { GuardValue( inType ); inType = true; } else if ( type->get_lvalue() ) { type->set_lvalue( false ); } } }; class TopLvaluePrint : public WithGuards, public WithShortCircuiting { bool failed = false; bool inType = false; bool typeTop = false; public: bool failedAny = false; void previsit() { if ( failed ) { visit_children = false; } else if ( typeTop ) { GuardValue( typeTop ); typeTop = false; } } void previsit( const BaseSyntaxNode * ) { previsit(); if ( inType ) { GuardValue( inType ); inType = false; } } void previsit( const Type * type ) { previsit(); if ( inType ) { if ( type->get_lvalue() ) { failed = true; failedAny = true; visit_children = false; std::cout << type->location << std::endl; } //assert( !type->get_lvalue() ); } else { GuardValue( inType ); inType = true; typeTop = true; } } void postvisit( const Type * type ) { if ( typeTop ) { if ( failed ) { std::cout << type->location << std::endl; type->print( std::cout ); //assert( !failed ); failed = false; } typeTop = false; } } }; } void assertTopLvalue( const std::list< Declaration * > & translationUnit ) { PassVisitor< TopLvaluePrint > visitor; acceptAll( translationUnit, visitor ); assert( !visitor.pass.failedAny ); } void clearInnerLvalue( std::list< Declaration * > & translationUnit ) { PassVisitor< ClearLvalue > visitor; acceptAll( translationUnit, visitor ); } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //