Changeset 4c03e63 for src/SymTab


Ignore:
Timestamp:
Jun 23, 2017, 4:20:33 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, stuck-waitfor-destruct, with_gc
Children:
74e58ea3, 7bbba76
Parents:
e1c1829 (diff), 88177cf (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 branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/SymTab
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.h

    re1c1829 r4c03e63  
    1010// Created On       : Sun May 17 21:53:34 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:10:41 2017
    13 // Update Count     : 9
     12// Last Modified On : Wed Jun 21 17:25:26 2017
     13// Update Count     : 14
    1414//
    1515
     
    2525
    2626namespace SymTab {
    27         /// Generates assignment operators, constructors, and destructor for aggregate types as required
    28         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 );
    2929
    30         /// returns true if obj's name is the empty string and it has a bitfield width
    31         bool isUnnamedBitfield( ObjectDecl * obj );
     30    /// returns true if obj's name is the empty string and it has a bitfield width
     31    bool isUnnamedBitfield( ObjectDecl * obj );
    3232
    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;
     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;
    3636
    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 >
     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 >
    3939        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
    4040
    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 >
     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 >
    4444        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 ) );
     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 ) );
    4848
    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();
     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();
    6060//                      castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
    61                         castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    62                         castType->set_lvalue( true ); // xxx - might not need this
    63                         dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    64                 }
    65                 fExpr->get_args().push_back( dstParam );
     61            castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     62            castType->set_lvalue( true ); // xxx - might not need this
     63            dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
     64        }
     65        fExpr->get_args().push_back( dstParam );
    6666
    67                 Statement * listInit = srcParam.buildListInit( fExpr );
     67        Statement * listInit = srcParam.buildListInit( fExpr );
    6868
    69                 std::list< Expression * > args = *++srcParam;
    70                 fExpr->get_args().splice( fExpr->get_args().end(), args );
     69        std::list< Expression * > args = *++srcParam;
     70        fExpr->get_args().splice( fExpr->get_args().end(), args );
    7171
    72                 *out++ = new ExprStmt( noLabels, fExpr );
     72        *out++ = new ExprStmt( noLabels, fExpr );
    7373
    74                 srcParam.clearArrayIndices();
     74        srcParam.clearArrayIndices();
    7575
    76                 return listInit;
     76        return listInit;
     77    }
     78
     79    /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
     80    /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
     81    template< typename OutputIterator >
     82        void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
     83        static UniqueName indexName( "_index" );
     84
     85        // for a flexible array member nothing is done -- user must define own assignment
     86        if ( ! array->get_dimension() ) return ;
     87
     88        Expression * begin, * end, * update, * cmp;
     89        if ( forward ) {
     90            // generate: for ( int i = 0; i < N; ++i )
     91            begin = new ConstantExpr( Constant::from_int( 0 ) );
     92            end = array->get_dimension()->clone();
     93            cmp = new NameExpr( "?<?" );
     94            update = new NameExpr( "++?" );
     95        } else {
     96            // generate: for ( int i = N-1; i >= 0; --i )
     97            begin = new UntypedExpr( new NameExpr( "?-?" ) );
     98            ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     99            ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     100            end = new ConstantExpr( Constant::from_int( 0 ) );
     101            cmp = new NameExpr( "?>=?" );
     102            update = new NameExpr( "--?" );
    77103        }
    78104
    79         /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    80         /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    81         template< typename OutputIterator >
    82         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
    83                 static UniqueName indexName( "_index" );
     105        ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
    84106
    85                 // for a flexible array member nothing is done -- user must define own assignment
    86                 if ( ! array->get_dimension() ) return ;
     107        UntypedExpr *cond = new UntypedExpr( cmp );
     108        cond->get_args().push_back( new VariableExpr( index ) );
     109        cond->get_args().push_back( end );
    87110
    88                 Expression * begin, * end, * update, * cmp;
    89                 if ( forward ) {
    90                         // generate: for ( int i = 0; i < 0; ++i )
    91                         begin = new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0" ) );
    92                         end = array->get_dimension()->clone();
    93                         cmp = new NameExpr( "?<?" );
    94                         update = new NameExpr( "++?" );
    95                 } else {
    96                         // generate: for ( int i = N-1; i >= 0; --i )
    97                         begin = new UntypedExpr( new NameExpr( "?-?" ) );
    98                         ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    99                         ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant( new OneType( emptyQualifiers ), "1" ) ) );
    100                         end = new ConstantExpr( Constant( new ZeroType( emptyQualifiers ), "0" ) );
    101                         cmp = new NameExpr( "?>=?" );
    102                         update = new NameExpr( "--?" );
    103                 }
     111        UntypedExpr *inc = new UntypedExpr( update );
     112        inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    104113
    105                 ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
     114        UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     115        dstIndex->get_args().push_back( dstParam );
     116        dstIndex->get_args().push_back( new VariableExpr( index ) );
     117        dstParam = dstIndex;
    106118
    107                 UntypedExpr *cond = new UntypedExpr( cmp );
    108                 cond->get_args().push_back( new VariableExpr( index ) );
    109                 cond->get_args().push_back( end );
     119        // srcParam must keep track of the array indices to build the
     120        // source parameter and/or array list initializer
     121        srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    110122
    111                 UntypedExpr *inc = new UntypedExpr( update );
    112                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     123        // for stmt's body, eventually containing call
     124        CompoundStmt * body = new CompoundStmt( noLabels );
     125        Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
    113126
    114                 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    115                 dstIndex->get_args().push_back( dstParam );
    116                 dstIndex->get_args().push_back( new VariableExpr( index ) );
    117                 dstParam = dstIndex;
     127        // block containing for stmt and index variable
     128        std::list<Statement *> initList;
     129        CompoundStmt * block = new CompoundStmt( noLabels );
     130        block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     131        if ( listInit ) block->get_kids().push_back( listInit );
     132        block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
    118133
    119                 // srcParam must keep track of the array indices to build the
    120                 // source parameter and/or array list initializer
    121                 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
     134        *out++ = block;
     135    }
    122136
    123                 // for stmt's body, eventually containing call
    124                 CompoundStmt * body = new CompoundStmt( noLabels );
    125                 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     137    template< typename OutputIterator >
     138        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
     139        if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     140            genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     141            return 0;
     142        } else {
     143            return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     144        }
     145    }
    126146
    127                 // block containing for stmt and index variable
    128                 std::list<Statement *> initList;
    129                 CompoundStmt * block = new CompoundStmt( noLabels );
    130                 block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    131                 if ( listInit ) block->get_kids().push_back( listInit );
    132                 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     147    /// inserts into out a generated call expression to function fname with arguments dstParam
     148    /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     149    /// object being constructed. The function wraps constructor and destructor calls in an
     150    /// ImplicitCtorDtorStmt node.
     151    template< typename OutputIterator >
     152        void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     153        ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
     154        assert( obj );
     155        // unnamed bit fields are not copied as they cannot be accessed
     156        if ( isUnnamedBitfield( obj ) ) return;
    133157
    134                 *out++ = block;
     158        bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
     159        std::list< Statement * > stmts;
     160        genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
     161
     162        // 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
     163        assert( stmts.size() <= 1 );
     164        if ( stmts.size() == 1 ) {
     165            Statement * callStmt = stmts.front();
     166            if ( addCast ) {
     167                // implicitly generated ctor/dtor calls should be wrapped
     168                // so that later passes are aware they were generated.
     169                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     170                // because this causes the address to be taken at codegen, which is illegal in C.
     171                callStmt = new ImplicitCtorDtorStmt( callStmt );
     172            }
     173            *out++ = callStmt;
    135174        }
    136 
    137         template< typename OutputIterator >
    138         Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    139                 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    140                         genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
    141                         return 0;
    142                 } else {
    143                         return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
    144                 }
    145         }
    146 
    147         /// inserts into out a generated call expression to function fname with arguments dstParam
    148         /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
    149         /// object being constructed. The function wraps constructor and destructor calls in an
    150         /// ImplicitCtorDtorStmt node.
    151         template< typename OutputIterator >
    152         void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    153                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    154                 assert( obj );
    155                 // unnamed bit fields are not copied as they cannot be accessed
    156                 if ( isUnnamedBitfield( obj ) ) return;
    157 
    158                 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
    159                 std::list< Statement * > stmts;
    160                 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
    161 
    162                 // 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
    163                 assert( stmts.size() <= 1 );
    164                 if ( stmts.size() == 1 ) {
    165                         Statement * callStmt = stmts.front();
    166                         if ( addCast ) {
    167                                 // implicitly generated ctor/dtor calls should be wrapped
    168                                 // so that later passes are aware they were generated.
    169                                 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    170                                 // because this causes the address to be taken at codegen, which is illegal in C.
    171                                 callStmt = new ImplicitCtorDtorStmt( callStmt );
    172                         }
    173                         *out++ = callStmt;
    174                 }
    175         }
     175    }
    176176} // namespace SymTab
    177177#endif // AUTOGEN_H
  • src/SymTab/Indexer.cc

    re1c1829 r4c03e63  
    493493                acceptNewScope( compLitExpr->get_result(), *this );
    494494                maybeAccept( compLitExpr->get_initializer(), *this );
    495         }
    496 
    497         void Indexer::visit( UntypedValofExpr *valofExpr ) {
    498                 acceptNewScope( valofExpr->get_result(), *this );
    499                 maybeAccept( valofExpr->get_body(), *this );
    500495        }
    501496
  • src/SymTab/Indexer.h

    re1c1829 r4c03e63  
    6969                virtual void visit( ConstructorExpr * ctorExpr );
    7070                virtual void visit( CompoundLiteralExpr *compLitExpr );
    71                 virtual void visit( UntypedValofExpr *valofExpr );
    7271                virtual void visit( RangeExpr *rangeExpr );
    7372                virtual void visit( UntypedTupleExpr *tupleExpr );
  • src/SymTab/Validate.cc

    re1c1829 r4c03e63  
    6666#include "ResolvExpr/typeops.h"
    6767
     68#include "SynTree/Attribute.h"
    6869#include "SynTree/Expression.h"
    6970#include "SynTree/Mutator.h"
     
    114115
    115116        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    116         class EnumAndPointerDecayPass final : public Visitor {
    117                 typedef Visitor Parent;
    118                 virtual void visit( EnumDecl *aggregateDecl );
    119                 virtual void visit( FunctionType *func );
     117        class EnumAndPointerDecay {
     118        public:
     119                void previsit( EnumDecl *aggregateDecl );
     120                void previsit( FunctionType *func );
    120121        };
    121122
     
    125126          public:
    126127                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    127           private:
    128128                using Parent::visit;
    129129                void visit( EnumInstType *enumInst ) final;
     
    135135                void visit( UnionDecl *unionDecl ) final;
    136136                void visit( TypeInstType *typeInst ) final;
    137 
     137          private:
    138138                const Indexer *indexer;
    139139
     
    146146        };
    147147
    148         /// Replaces array and function types in forall lists by appropriate pointer type
    149         class Pass3 final : public Indexer {
     148        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
     149        class ForallPointerDecay final : public Indexer {
    150150                typedef Indexer Parent;
    151151          public:
    152152                using Parent::visit;
    153                 Pass3( const Indexer *indexer );
    154           private:
     153                ForallPointerDecay( const Indexer *indexer );
     154
    155155                virtual void visit( ObjectDecl *object ) override;
    156156                virtual void visit( FunctionDecl *func ) override;
     
    159159        };
    160160
    161         class ReturnChecker {
     161        class ReturnChecker : public WithScopes {
    162162          public:
    163163                /// Checks that return statements return nothing if their return type is void
     
    166166          private:
    167167                void previsit( FunctionDecl * functionDecl );
    168                 void postvisit( FunctionDecl * functionDecl );
    169168                void previsit( ReturnStmt * returnStmt );
    170169
    171170                typedef std::list< DeclarationWithType * > ReturnVals;
    172171                ReturnVals returnVals;
    173                 std::stack< ReturnVals > returnValsStack;
    174172        };
    175173
     
    247245
    248246        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    249                 EnumAndPointerDecayPass epc;
     247                PassVisitor<EnumAndPointerDecay> epc;
    250248                LinkReferenceToTypes lrt( doDebug, 0 );
    251                 Pass3 pass3( 0 );
     249                ForallPointerDecay fpd( 0 );
    252250                CompoundLiteral compoundliteral;
    253251                PassVisitor<ValidateGenericParameters> genericParams;
     
    261259                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    262260                Concurrency::applyKeywords( translationUnit );
    263                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     261                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    264262                Concurrency::implementMutexFuncs( translationUnit );
    265263                Concurrency::implementThreadStarter( translationUnit );
    266264                ReturnChecker::checkFunctionReturns( translationUnit );
    267265                compoundliteral.mutateDeclarationList( translationUnit );
    268                 acceptAll( translationUnit, pass3 );
     266                acceptAll( translationUnit, fpd );
    269267                ArrayLength::computeLength( translationUnit );
    270268        }
    271269
    272270        void validateType( Type *type, const Indexer *indexer ) {
    273                 EnumAndPointerDecayPass epc;
     271                PassVisitor<EnumAndPointerDecay> epc;
    274272                LinkReferenceToTypes lrt( false, indexer );
    275                 Pass3 pass3( indexer );
     273                ForallPointerDecay fpd( indexer );
    276274                type->accept( epc );
    277275                type->accept( lrt );
    278                 type->accept( pass3 );
     276                type->accept( fpd );
    279277        }
    280278
     
    355353        }
    356354
    357         void EnumAndPointerDecayPass::visit( EnumDecl *enumDecl ) {
     355        void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
    358356                // Set the type of each member of the enumeration to be EnumConstant
    359357                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     
    362360                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
    363361                } // for
    364                 Parent::visit( enumDecl );
    365362        }
    366363
     
    369366                void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    370367                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    371                         // entirely other fix ups are handled by the FixFunction class
     368                        // entirely. other fix ups are handled by the FixFunction class
    372369                        typedef typename DWTList::iterator DWTIterator;
    373370                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
     
    388385                                for ( ; i != end; ++i ) {
    389386                                        FixFunction fixer;
    390                                         *i = (*i )->acceptMutator( fixer );
     387                                        *i = (*i)->acceptMutator( fixer );
    391388                                        if ( fixer.get_isVoid() ) {
    392389                                                throw SemanticError( "invalid type void in function type ", func );
     
    397394        }
    398395
    399         void EnumAndPointerDecayPass::visit( FunctionType *func ) {
     396        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    400397                // Fix up parameters and return types
    401398                fixFunctionList( func->get_parameters(), func );
    402399                fixFunctionList( func->get_returnVals(), func );
    403                 Visitor::visit( func );
    404400        }
    405401
     
    548544        }
    549545
    550         Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
     546        ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
    551547                if ( other_indexer ) {
    552548                        indexer = other_indexer;
     
    586582        }
    587583
    588         void Pass3::visit( ObjectDecl *object ) {
     584        void ForallPointerDecay::visit( ObjectDecl *object ) {
    589585                forallFixer( object->get_type() );
    590586                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     
    595591        }
    596592
    597         void Pass3::visit( FunctionDecl *func ) {
     593        void ForallPointerDecay::visit( FunctionDecl *func ) {
    598594                forallFixer( func->get_type() );
    599595                Parent::visit( func );
     
    607603
    608604        void ReturnChecker::previsit( FunctionDecl * functionDecl ) {
    609                 returnValsStack.push( returnVals );
     605                GuardValue( returnVals );
    610606                returnVals = functionDecl->get_functionType()->get_returnVals();
    611         }
    612         void ReturnChecker::postvisit( __attribute__((unused)) FunctionDecl * functionDecl ) {
    613                 returnVals = returnValsStack.top();
    614                 returnValsStack.pop();
    615607        }
    616608
     
    927919                                ret->set_name( toString( "_retval_", CodeGen::genName( functionDecl ) ) );
    928920                        }
     921                        ret->get_attributes().push_back( new Attribute( "unused" ) );
    929922                }
    930923        }
Note: See TracChangeset for help on using the changeset viewer.