Changeset c331406 for src/SymTab


Ignore:
Timestamp:
Aug 5, 2016, 11:03:04 AM (8 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
a2f920f
Parents:
5070fe4 (diff), 1b0020a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge changes from master

Location:
src/SymTab
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/AddVisit.h

    r5070fe4 rc331406  
    1010// Created On       : Sun May 17 16:14:32 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 12 17:46:33 2016
    13 // Update Count     : 6
     12// Last Modified On : Thu Aug  4 11:22:01 2016
     13// Update Count     : 9
    1414//
    1515
     
    3333        template< typename Visitor >
    3434        inline void addVisit(SwitchStmt *switchStmt, Visitor &visitor) {
    35                 addVisitStatementList( switchStmt->get_branches(), visitor );
     35                addVisitStatementList( switchStmt->get_statements(), visitor );
    3636                maybeAccept( switchStmt->get_condition(), visitor );
    3737        }
  • src/SymTab/Autogen.cc

    r5070fe4 rc331406  
    2626
    2727namespace SymTab {
     28        Type * SizeType = 0;
     29
    2830        class AutogenerateRoutines : public Visitor {
    2931                public:
     
    5961        bool isUnnamedBitfield( ObjectDecl * obj ) {
    6062                return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
    61         }
    62 
    63         template< typename OutputIterator >
    64         void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
    65                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    66                 // unnamed bit fields are not copied as they cannot be accessed
    67                 if ( isUnnamedBitfield( obj ) ) return;
    68 
    69                 // want to be able to generate assignment, ctor, and dtor generically,
    70                 // so fname is either ?=?, ?{}, or ^?{}
    71                 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    72 
    73                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    74                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    75 
    76                 // do something special for unnamed members
    77                 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    78                 fExpr->get_args().push_back( dstselect );
    79 
    80                 if ( src ) {
    81                         fExpr->get_args().push_back( src );
    82                 }
    83 
    84                 Statement * callStmt = new ExprStmt( noLabels, fExpr );
    85                 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {
    86                         // implicitly generated ctor/dtor calls should be wrapped
    87                         // so that later passes are aware they were generated.
    88                         // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    89                         // because this causes the address to be taken at codegen, which is illegal in C.
    90                         callStmt = new ImplicitCtorDtorStmt( callStmt );
    91                 }
    92                 *out++ = callStmt;
    9363        }
    9464
     
    219189                }
    220190
     191                InitTweak::InitExpander srcParam( src );
     192
    221193                // assign to destination (and return value if generic)
    222                 if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) {
    223                         UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    224                         derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    225                         Expression *dstselect = new MemberExpr( field, derefExpr );
    226 
    227                         makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
    228                         if ( isDynamicLayout && returnVal ) {
    229                                 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
    230                                 derefRet->get_args().push_back( new VariableExpr( returnVal ) );
    231                                 Expression *retselect = new MemberExpr( field, derefRet );
    232 
    233                                 makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
    234                         }
    235                 } else {
    236                         makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    237                         if ( isDynamicLayout && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     194                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     195                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     196                Expression *dstselect = new MemberExpr( field, derefExpr );
     197                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     198
     199                if ( isDynamicLayout && returnVal ) {
     200                        UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
     201                        derefRet->get_args().push_back( new VariableExpr( returnVal ) );
     202                        Expression *retselect = new MemberExpr( field, derefRet );
     203                        genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    238204                } // if
    239205        }
  • src/SymTab/Autogen.h

    r5070fe4 rc331406  
    2222#include "SynTree/Declaration.h"
    2323#include "SynTree/Initializer.h"
     24#include "InitTweak/InitTweak.h"
    2425
    2526namespace SymTab {
    26   /// Generates assignment operators, constructors, and destructor for aggregate types as required
    27   void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     27        /// Generates assignment operators, constructors, and destructor for aggregate types as required
     28        void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    2829
    29   // originally makeArrayAssignment - changed to Function because it is now used for ctors and dtors as well
    30   // admittedly not a great name change. This used to live in Validate.cc, but has been moved so it can be reused elsewhere
     30        /// returns true if obj's name is the empty string and it has a bitfield width
     31        bool isUnnamedBitfield( ObjectDecl * obj );
    3132
    32   /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    33   /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    34   template< typename OutputIterator >
    35   void makeArrayFunction( Expression *srcParam, Expression *dstParam, ArrayType *array, std::string fname, OutputIterator out, bool forward = true ) {
    36     static UniqueName indexName( "_index" );
     33        /// size_t type - set when size_t typedef is seen. Useful in a few places,
     34        /// such as in determining array dimension type
     35        extern Type * SizeType;
    3736
    38     // for a flexible array member nothing is done -- user must define own assignment
    39     if ( ! array->get_dimension() ) return;
     37        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
     38        template< typename OutputIterator >
     39        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
    4040
    41     Expression * begin, * end, * update, * cmp;
    42     if ( forward ) {
    43       // generate: for ( int i = 0; i < 0; ++i )
    44       begin = new NameExpr( "0" );
    45       end = array->get_dimension()->clone();
    46       cmp = new NameExpr( "?<?" );
    47       update = new NameExpr( "++?" );
    48     } else {
    49       // generate: for ( int i = N-1; i >= 0; --i )
    50       begin = new UntypedExpr( new NameExpr( "?-?" ) );
    51       ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    52       ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) );
    53       end = new NameExpr( "0" );
    54       cmp = new NameExpr( "?>=?" );
    55       update = new NameExpr( "--?" );
    56     }
     41        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
     42        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
     43        template< typename OutputIterator >
     44        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
     45                // want to be able to generate assignment, ctor, and dtor generically,
     46                // so fname is either ?=?, ?{}, or ^?{}
     47                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    5748
    58     ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
     49                // do something special for unnamed members
     50                dstParam = new AddressExpr( dstParam );
     51                if ( addCast ) {
     52                        // cast to T* with qualifiers removed, so that qualified objects can be constructed
     53                        // and destructed with the same functions as non-qualified objects.
     54                        // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     55                        // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     56                        // remove lvalue as a qualifier, this can change to
     57                        //   type->get_qualifiers() = Type::Qualifiers();
     58                        assert( type );
     59                        Type * castType = type->clone();
     60                        castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     61                        castType->set_isLvalue( true ); // xxx - might not need this
     62                        dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
     63                }
     64                fExpr->get_args().push_back( dstParam );
    5965
    60     UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    61     init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    62     init->get_args().push_back( begin );
    63     index->set_init( new SingleInit( init, std::list<Expression*>() ) );
     66                Statement * listInit = srcParam.buildListInit( fExpr );
    6467
    65     UntypedExpr *cond = new UntypedExpr( cmp );
    66     cond->get_args().push_back( new VariableExpr( index ) );
    67     cond->get_args().push_back( end );
     68                std::list< Expression * > args = *++srcParam;
     69                fExpr->get_args().splice( fExpr->get_args().end(), args );
    6870
    69     UntypedExpr *inc = new UntypedExpr( update );
    70     inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     71                *out++ = new ExprStmt( noLabels, fExpr );
    7172
    72     // want to be able to generate assignment, ctor, and dtor generically,
    73     // so fname is either ?=?, ?{}, or ^?{}
    74     UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
     73                srcParam.clearArrayIndices();
    7574
    76     UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
    77     dstIndex->get_args().push_back( dstParam );
    78     dstIndex->get_args().push_back( new VariableExpr( index ) );
    79     fExpr->get_args().push_back( dstIndex );
     75                return listInit;
     76        }
    8077
    81     // srcParam is NULL for default ctor/dtor
    82     if ( srcParam ) {
    83       UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    84       srcIndex->get_args().push_back( srcParam );
    85       srcIndex->get_args().push_back( new VariableExpr( index ) );
    86       fExpr->get_args().push_back( srcIndex );
    87     }
     78        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
     79        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
     80        template< typename OutputIterator >
     81        void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
     82                static UniqueName indexName( "_index" );
    8883
    89     std::list<Statement *> initList;
    90     CompoundStmt * block = new CompoundStmt( noLabels );
    91     block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    92     block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) ) );
     84                // for a flexible array member nothing is done -- user must define own assignment
     85                if ( ! array->get_dimension() ) return ;
    9386
    94     Statement * stmt = block;
    95     if ( fname == "?{}" || fname == "^?{}" ) {
    96       // implicitly generated ctor/dtor calls should be wrapped
    97       // so that later passes are aware they were generated
    98       stmt = new ImplicitCtorDtorStmt( stmt );
    99     }
    100     *out++ = stmt;
    101   }
     87                Expression * begin, * end, * update, * cmp;
     88                if ( forward ) {
     89                        // generate: for ( int i = 0; i < 0; ++i )
     90                        begin = new NameExpr( "0" );
     91                        end = array->get_dimension()->clone();
     92                        cmp = new NameExpr( "?<?" );
     93                        update = new NameExpr( "++?" );
     94                } else {
     95                        // generate: for ( int i = N-1; i >= 0; --i )
     96                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
     97                        ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     98                        ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) );
     99                        end = new NameExpr( "0" );
     100                        cmp = new NameExpr( "?>=?" );
     101                        update = new NameExpr( "--?" );
     102                }
     103
     104                ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
     105
     106                UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
     107                init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     108                init->get_args().push_back( begin );
     109                index->set_init( new SingleInit( init, std::list<Expression*>() ) );
     110
     111                UntypedExpr *cond = new UntypedExpr( cmp );
     112                cond->get_args().push_back( new VariableExpr( index ) );
     113                cond->get_args().push_back( end );
     114
     115                UntypedExpr *inc = new UntypedExpr( update );
     116                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     117
     118                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     119                dstIndex->get_args().push_back( dstParam );
     120                dstIndex->get_args().push_back( new VariableExpr( index ) );
     121                dstParam = dstIndex;
     122
     123                // srcParam must keep track of the array indices to build the
     124                // source parameter and/or array list initializer
     125                srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
     126
     127                // for stmt's body, eventually containing call
     128                CompoundStmt * body = new CompoundStmt( noLabels );
     129                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     130
     131                // block containing for stmt and index variable
     132                std::list<Statement *> initList;
     133                CompoundStmt * block = new CompoundStmt( noLabels );
     134                block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     135                if ( listInit ) block->get_kids().push_back( listInit );
     136                block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     137
     138                *out++ = block;
     139        }
     140
     141        template< typename OutputIterator >
     142        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
     143                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     144                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     145                        return 0;
     146                } else {
     147                        return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     148                }
     149        }
     150
     151        /// inserts into out a generated call expression to function fname with arguments dstParam
     152        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     153        /// object being constructed. The function wraps constructor and destructor calls in an
     154        /// ImplicitCtorDtorStmt node.
     155        template< typename OutputIterator >
     156        void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     157                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
     158                assert( obj );
     159                // unnamed bit fields are not copied as they cannot be accessed
     160                if ( isUnnamedBitfield( obj ) ) return;
     161
     162                bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
     163                std::list< Statement * > stmts;
     164                genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
     165
     166                // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
     167                assert( stmts.size() <= 1 );
     168                if ( stmts.size() == 1 ) {
     169                        Statement * callStmt = stmts.front();
     170                        if ( addCast ) {
     171                                // implicitly generated ctor/dtor calls should be wrapped
     172                                // so that later passes are aware they were generated.
     173                                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     174                                // because this causes the address to be taken at codegen, which is illegal in C.
     175                                callStmt = new ImplicitCtorDtorStmt( callStmt );
     176                        }
     177                        *out++ = callStmt;
     178                }
     179        }
    102180} // namespace SymTab
    103181#endif // AUTOGEN_H
  • src/SymTab/FixFunction.cc

    r5070fe4 rc331406  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixFunction.cc -- 
     7// FixFunction.cc --
    88//
    99// Author           : Richard C. Bilson
     
    4444
    4545        Type * FixFunction::mutate(ArrayType *arrayType) {
    46                 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
     46                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
     47                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
    4748                delete arrayType;
    4849                return pointerType;
  • src/SymTab/Validate.cc

    r5070fe4 rc331406  
    174174
    175175                virtual void visit( FunctionDecl *funcDecl );
    176 };
     176        };
    177177
    178178        class CompoundLiteral : public GenPoly::DeclMutator {
     
    191191                EliminateTypedef::eliminateTypedef( translationUnit );
    192192                HoistStruct::hoistStruct( translationUnit );
     193                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1
    193194                acceptAll( translationUnit, pass1 );
    194195                acceptAll( translationUnit, pass2 );
    195196                ReturnChecker::checkFunctionReturns( translationUnit );
    196                 mutateAll( translationUnit, compoundliteral );
    197                 autogenerateRoutines( translationUnit );
     197                compoundliteral.mutateDeclarationList( translationUnit );
    198198                acceptAll( translationUnit, pass3 );
    199199                VerifyCtorDtor::verify( translationUnit );
     
    490490                EliminateTypedef eliminator;
    491491                mutateAll( translationUnit, eliminator );
     492                if ( eliminator.typedefNames.count( "size_t" ) ) {
     493                        // grab and remember declaration of size_t
     494                        SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone();
     495                } else {
     496                        // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
     497                        // eventually should have a warning for this case.
     498                        SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     499                }
    492500                filter( translationUnit, isTypedef, true );
     501
    493502        }
    494503
     
    518527        Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
    519528                Declaration *ret = Mutator::mutate( tyDecl );
     529
    520530                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    521531                        // typedef to the same name from the same scope
Note: See TracChangeset for help on using the changeset viewer.