Changes in / [36ebd03:4040425]


Ignore:
Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r36ebd03 r4040425  
    2222
    2323#include "Box.h"
    24 #include "DeclMutator.h"
    2524#include "InstantiateGeneric.h"
    2625#include "PolyMutator.h"
     
    5554                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5655
    57                 /// Adds layout-generation functions to polymorphic types
    58                 class LayoutFunctionBuilder : public DeclMutator {
    59                         unsigned int functionNesting;  // current level of nested functions
    60                 public:
    61                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    62 
    63                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
    64                         virtual Declaration *mutate( StructDecl *structDecl );
    65                         virtual Declaration *mutate( UnionDecl *unionDecl );
    66                 };
    67                
    6856                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    6957                class Pass1 : public PolyMutator {
     
    171159        } // anonymous namespace
    172160
     161        void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {
     162                for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     163                        if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
     164                                (*i)->print( os );
     165                                os << std::endl;
     166                        } // if
     167                } // for
     168        }
     169
    173170        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
    174171        template< typename MutatorType >
     
    198195
    199196        void box( std::list< Declaration *>& translationUnit ) {
    200                 LayoutFunctionBuilder layoutBuilder;
    201197                Pass1 pass1;
    202198                Pass2 pass2;
    203199                MemberExprFixer memberFixer;
    204200                Pass3 pass3;
    205                 layoutBuilder.mutateDeclarationList( translationUnit );
    206201                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    207202                mutateTranslationUnit/*All*/( translationUnit, pass2 );
     
    211206        }
    212207
    213         ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    214 
    215         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    216                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    217                 mutateAll( functionDecl->get_oldDecls(), *this );
    218                 ++functionNesting;
    219                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    220                 --functionNesting;
    221                 return functionDecl;
    222         }
    223        
    224         /// Get a list of type declarations that will affect a layout function
    225         std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
    226                 std::list< TypeDecl * > otypeDecls;
    227 
    228                 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    229                         if ( decl->get_kind() == TypeDecl::Any ) {
    230                                 otypeDecls.push_back( *decl );
    231                         }
    232                 }
    233                
    234                 return otypeDecls;
    235         }
    236 
    237         /// Adds parameters for otype layout to a function type
    238         void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    239                 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    240                
    241                 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    242                         layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( (*param)->get_base() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    243                 }
    244         }
    245 
    246         /// Builds a layout function declaration
    247         FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {
    248                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    249                 // because each unit generates copies of the default routines for each aggregate.
    250                 FunctionDecl *layoutDecl = new FunctionDecl(
    251                         "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
    252                 layoutDecl->fixUniqueId();
    253                 return layoutDecl;
    254         }
    255 
    256         /// Makes a unary operation
    257         Expression *makeOp( const std::string &name, Expression *arg ) {
    258                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    259                 expr->get_args().push_back( arg );
    260                 return expr;
    261         }
    262 
    263         /// Makes a binary operation
    264         Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {
    265                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    266                 expr->get_args().push_back( lhs );
    267                 expr->get_args().push_back( rhs );
    268                 return expr;
    269         }
    270 
    271         /// Returns the dereference of a local pointer variable
    272         Expression *derefVar( ObjectDecl *var ) {
    273                 return makeOp( "*?", new VariableExpr( var ) );
    274         }
    275 
    276         /// makes an if-statement with a single-expression if-block and no then block
    277         Statement *makeCond( Expression *cond, Expression *ifPart ) {
    278                 return new IfStmt( noLabels, cond, new ExprStmt( ifPart ), 0 );
    279         }
    280 
    281         /// makes a statement that assigns rhs to lhs if lhs < rhs
    282         Statement *makeAssignMax( Expression *lhs, Expression *rhs ) {
    283                 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) );
    284         }
    285 
    286         /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two)
    287         Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
    288                 // check that the lhs is zeroed out to the level of rhs
    289                 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );
    290                 // if not aligned, increment to alignment
    291                 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
    292                 return makeCond( ifCond, ifExpr );
    293         }
    294        
    295         /// adds an expression to a compound statement
    296         void addExpr( CompoundStmt *stmts, Expression *expr ) {
    297                 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );
    298         }
    299 
    300         /// adds a statement to a compound statement
    301         void addStmt( CompoundStmt *stmts, Statement *stmt ) {
    302                 stmts->get_kids().push_back( stmt );
    303         }
    304        
    305         virtual Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    306                 // do not generate layout function for "empty" tag structs
    307                 if ( structDecl->get_members().empty() ) return structDecl;
    308 
    309                 // get parameters that can change layout, exiting early if none
    310                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    311                 if ( otypeParams.empty() ) return structDecl;
    312 
    313                 // build layout function signature
    314                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    315                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    316                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    317                
    318                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    319                 layoutFnType->get_parameters().push_back( sizeParam );
    320                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    321                 layoutFnType->get_parameters().push_back( alignParam );
    322                 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    323                 layoutFnType->get_parameters().push_back( offsetParam );
    324                 addOtypeParams( layoutFnType, otypeParams );
    325 
    326                 // build function decl
    327                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );
    328 
    329                 // calculate struct layout in function body
    330 
    331                 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size
    332                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
    333                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    334                 unsigned long n_members = 0;
    335                 bool firstMember = true;
    336                 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
    337                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    338                         assert( dwt );
    339 
    340                         if ( firstMember ) {
    341                                 firstMember = false;
    342                         } else {
    343                                 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    344                                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( dwt->get_type() ) ) );
    345                         }
    346                        
    347                         // place current size in the current offset index
    348                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
    349                                                                               derefVar( sizeParam ) ) );
    350                         ++n_members;
    351 
    352                         // add member size to current size
    353                         addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( dwt->get_type() ) ) );
    354                        
    355                         // take max of member alignment and global alignment
    356                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( dwt->get_type() ) ) );
    357                 }
    358                 // make sure the type is end-padded to a multiple of its alignment
    359                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    360 
    361                 addDeclarationAfter( layoutDecl );
    362                 return structDecl;
    363         }
    364        
    365         virtual Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    366                 // do not generate layout function for "empty" tag unions
    367                 if ( unionDecl->get_members().empty() ) return unionDecl;
    368                
    369                 // get parameters that can change layout, exiting early if none
    370                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    371                 if ( otypeParams.empty() ) return unionDecl;
    372 
    373                 // build layout function signature
    374                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    375                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    376                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    377                
    378                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    379                 layoutFnType->get_parameters().push_back( sizeParam );
    380                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    381                 layoutFnType->get_parameters().push_back( alignParam );
    382                 addOtypeParams( layoutFnType, otypeParams );
    383 
    384                 // build function decl
    385                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );
    386 
    387                 // calculate union layout in function body
    388                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    389                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    390                 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
    391                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    392                         assert( dwt );
    393                        
    394                         // take max member size and global size
    395                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( dwt->get_type() ) ) );
    396                        
    397                         // take max of member alignment and global alignment
    398                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( dwt->get_type() ) ) );
    399                 }
    400                 // make sure the type is end-padded to a multiple of its alignment
    401                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    402 
    403                 addDeclarationAfter( layoutDecl );
    404                 return unionDecl;
    405         }
    406        
    407208        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    408209
  • src/GenPoly/DeclMutator.cc

    r36ebd03 r4040425  
    2424        }
    2525
    26         DeclMutator::DeclMutator() : Mutator(), declsToAdd(1), declsToAddAfter(1) {}
     26        DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {}
    2727
    2828        DeclMutator::~DeclMutator() {}
    2929       
    3030        void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) {
    31                 for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) {
    32                         // splice in new declarations after previous decl
    33                         decls.splice( decl, declsToAddAfter.back() );
    34 
    35                         if ( decl == decls.end() ) break;
    36                        
     31                for ( std::list< Declaration* >::iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    3732                        // run mutator on declaration
    3833                        *decl = maybeMutate( *decl, *this );
     
    4439
    4540        void DeclMutator::doBeginScope() {
    46                 // add new decl lists for inside of scope
     41                // add new decl list for inside of scope
    4742                declsToAdd.resize( declsToAdd.size()+1 );
    48                 declsToAddAfter.resize( declsToAddAfter.size()+1 );
    4943        }
    5044
     
    5549                newBack->splice( newBack->end(), *back );
    5650                declsToAdd.pop_back();
    57                
    58                 back = declsToAddAfter.rbegin();
    59                 newBack = back + 1;
    60                 newBack->splice( newBack->end(), *back );
    61                 declsToAddAfter.pop_back();
    6251        }
    6352
     
    7261                stmt = maybeMutate( stmt, *this );
    7362                // return if no declarations to add
    74                 if ( declsToAdd.back().empty() && declsToAddAfter.back().empty() ) {
    75                         doEndScope();
    76                         return stmt;
    77                 }
     63                if ( declsToAdd.back().empty() ) return stmt;
    7864
    7965                // otherwise add declarations to new compound statement
     
    8571                declsToAdd.back().clear();
    8672
    87                 // add mutated statement
     73                doEndScope();
     74
     75                // add mutated statement and return
    8876                compound->get_kids().push_back( stmt );
    89 
    90                 // add declarations after to new compound statement
    91                 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) {
    92                         DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
    93                         compound->get_kids().push_back( declStmt );
    94                 }
    95                 declsToAddAfter.back().clear();
    96 
    97                 doEndScope();
    9877                return compound;
    9978        }
     
    10180        void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) {
    10281                doBeginScope();
    103 
    10482               
    105                 for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) {
    106                         // add any new declarations after the previous statement
    107                         for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) {
    108                                 DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
    109                                 stmts.insert( stmt, declStmt );
    110                         }
    111                         declsToAddAfter.back().clear();
    112 
    113                         if ( stmt == stmts.end() ) break;
    114                        
     83                for ( std::list< Statement* >::iterator stmt = stmts.begin(); stmt != stmts.end(); ++stmt ) {
    11584                        // run mutator on statement
    11685                        *stmt = maybeMutate( *stmt, *this );
     
    12392                        declsToAdd.back().clear();
    12493                }
    125                
     94
    12695                doEndScope();
    12796        }
     
    12998        void DeclMutator::addDeclaration( Declaration *decl ) {
    13099                declsToAdd.back().push_back( decl );
    131         }
    132 
    133         void DeclMutator::addDeclarationAfter( Declaration *decl ) {
    134                 declsToAddAfter.back().push_back( decl );
    135100        }
    136101
  • src/GenPoly/DeclMutator.h

    r36ebd03 r4040425  
    5555                /// Add a declaration to the list to be added before the current position
    5656                void addDeclaration( Declaration* decl );
    57                 /// Add a declaration to the list to be added after the current position
    58                 void addDeclarationAfter( Declaration* decl );
    5957        private:
    6058                /// A stack of declarations to add before the current declaration or statement
    6159                std::vector< std::list< Declaration* > > declsToAdd;
    62                 /// A stack of declarations to add after the current declaration or statement
    63                 std::vector< std::list< Declaration* > > declsToAddAfter;
    6460        };
    6561} // namespace
  • src/SynTree/Constant.cc

    r36ebd03 r4040425  
    1616#include <iostream>
    1717#include <list>
    18 #include <string>
    1918
    2019#include "Constant.h"
     
    2928
    3029Constant::~Constant() { delete type; }
    31 
    32 Constant Constant::from( int i ) {
    33         return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) );
    34 }
    35 
    36 Constant Constant::from( unsigned long i ) {
    37         return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) );
    38 }
    39 
    40 Constant Constant::from( double d ) {
    41         return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) );
    42 }
    4330
    4431Constant *Constant::clone() const { assert( false ); return 0; }
  • src/SynTree/Constant.h

    r36ebd03 r4040425  
    3232        void set_value( std::string newValue ) { value = newValue; }
    3333
    34         /// generates an integer constant of the given int
    35         static Constant from( int i );
    36         /// generates an integer constant of the given unsigned long int
    37         static Constant from( unsigned long i );
    38         /// generates a floating point constant of the given double
    39         static Constant from( double d );
    40 
    4134        virtual Constant *clone() const;
    4235        virtual void accept( Visitor &v ) { v.visit( this ); }
Note: See TracChangeset for help on using the changeset viewer.