// // 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. // // BasicInit.h -- // // Author : Rodolfo G. Esteves // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Tue May 19 16:32:21 2015 // Update Count : 3 // #ifndef _BASINIT_H_ #define _BASINIT_H_ #include #include "SynTree/Visitor.h" #include "SymTab/Indexer.h" #include "SynTree/Type.h" #include "SynTree/Initializer.h" #include "SynTree/Expression.h" #include "NameInCollection.h" #include "NameAssociation.h" namespace InitTweak { bool isDeclStmtP(Statement *stmt); class BreakInitializer; class BreakDesignator; class BasicInit: public Mutator { public: BasicInit() : bindings( 0 ) {} BasicInit( SymTab::Indexer &_index ) : bindings( 0 ), index( _index ) {} BasicInit( const BasicInit &other ) { bindings = other.get_bindings(); index = other.index; } ~BasicInit() { /* delete bindings; bindings = 0; */ } NameAssociation< Expression *, BreakInitializer > *get_bindings() const { return bindings; } void set_bindings( NameAssociation< Expression *, BreakInitializer > *newValue ) { bindings = newValue; } bool has_bindings() { return ( get_bindings() != 0 || ! stmts.empty() ); } virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) { index.visit( objectDecl ); return objectDecl; } virtual TypeDecl *mutate( TypeDecl *typeDecl ) { index.visit( typeDecl ); return typeDecl; } virtual TypedefDecl *mutate( TypedefDecl *typeDecl ) { index.visit( typeDecl ); return typeDecl; } virtual StructDecl *mutate( StructDecl *aggregateDecl ) { index.visit( aggregateDecl ); return aggregateDecl; } virtual UnionDecl *mutate( UnionDecl *aggregateDecl ) { index.visit( aggregateDecl ); return aggregateDecl; } virtual EnumDecl *mutate( EnumDecl *aggregateDecl ) { index.visit( aggregateDecl ); return aggregateDecl; } virtual Type *mutate( StructInstType *aggrInst ) { index.visit( aggrInst ); return aggrInst; } virtual Type *mutate( UnionInstType *aggrInst ) { index.visit( aggrInst ); return aggrInst; } virtual CompoundStmt *mutate(CompoundStmt *compoundStmt); virtual Statement *mutate(DeclStmt *declStmt); std::list< Statement *> get_statements() const { return stmts; } static void build_statements( NameAssociation< Expression *, BreakInitializer > *assoc, std::string aggName, std::list< Statement *> &stmts ); private: NameAssociation< Expression *, BreakInitializer > *bindings; Statement *assignFromDecl( DeclStmt *declStmt ); SymTab::Indexer index; std::list< Statement *> stmts; class Classify { public: enum TypeKind { NULL_T, SINGLE_T, COMPOUND_T }; enum InitKind { NULL_I, SINGLE_I, COMPOUND_I }; static TypeKind type( Type * ); static InitKind initializer( Initializer *); static NameInCollection *declaration( ObjectDecl *objdecl, SymTab::Indexer *index ); static std::list< Statement * > matchInit( NameInCollection *, ObjectDecl *, Initializer * ); static Statement *constructAssgn( std::string membname, ObjectDecl *toInit, SingleInit *sinit ); // static std::list< Statement * > constructListAssgn( NameAssociation assoc ); }; }; class BreakInitializer { enum InitKind { EMPTY, SINGLE, COMPOUND }; class BreakDesignator; typedef BreakDesignator NameSplitter; public: typedef std::list::iterator element_iterator; typedef std::list< NameSplitter >::iterator name_iterator; BreakInitializer ( Initializer *_init ) : kind( EMPTY ), sinit(0), cinit(0) { std::list temp; if ( ( sinit=dynamic_cast< SingleInit * >(_init) ) != 0 ) { kind = SINGLE; temp = sinit->get_designators(); } else if ( ( cinit=dynamic_cast< ListInit * >(_init) ) != 0 ) { kind = COMPOUND; temp = cinit->get_designators(); } // if std::transform( temp.begin(), temp.end(), std::back_inserter( designators ), ctor_noptr ); } //BreakInitializer( const BreakInitializer &other ) { this.col = other.col; } ~BreakInitializer () {} BreakInitializer set_name( NameSplitter &name ) { designators.clear(); designators.push_back( name ); return *this; } element_iterator element_begin() { assert( cinit != 0 ); return cinit->begin_initializers(); } element_iterator element_end() { assert( cinit != 0 ); return cinit->end_initializers(); } name_iterator names_begin() { return designators.begin(); } name_iterator names_end() { return designators.end(); } int names_size() const { return designators.size(); } bool has_index() const { return ! designators.empty(); } bool is_single() const { return kind == SINGLE; } bool is_composite() const { return kind == COMPOUND; } Expression *get_value() { switch ( kind ) { case EMPTY: return 0; break; case SINGLE: return sinit->get_value(); break; case COMPOUND: assert(false); break; default: assert(false); } // switch return 0; } // attributes private: InitKind kind; SingleInit *sinit; ListInit *cinit; std::list< BreakDesignator > designators; // helper classes public: class BreakDesignator { public: BreakDesignator( Expression *exp ) { Expression *prfx = exp; UntypedMemberExpr *me = 0; do { if ( (me=dynamic_cast< UntypedMemberExpr * >( prfx )) == 0 ) break; blown_struct.push_front( me->get_member() ); prfx = me->get_aggregate(); } while ( prfx != 0 ); NameExpr *ne; if ( (ne=dynamic_cast< NameExpr * >( prfx )) != 0 ) blown_struct.push_front( ne->get_name() ); } BreakDesignator( std::string name ) { blown_struct.push_front( name ); } bool is_flat() const { return blown_struct.size() == 1; } bool is_nested() const { return blown_struct.size() > 1; } std::string get_name() { return blown_struct.front(); } BreakDesignator &name_remainder() { blown_struct.pop_front(); return *this; } private: std::list< std::string > blown_struct; }; }; } // namespace InitTweak #endif // _BASINIT_H_ // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //