Changes in / [ccb447e:31e46b8]


Ignore:
Location:
src
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/DeclMutator.h

    rccb447e r31e46b8  
    2828        class DeclMutator : public Mutator {
    2929        public:
    30                 typedef Mutator Parent;
    31 
    3230                DeclMutator();
    3331                virtual ~DeclMutator();
    34 
    35                 using Parent::mutate;
     32               
    3633                virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
    3734                virtual Statement* mutate(IfStmt *ifStmt);
     
    4542                /// Mutates a list of declarations with this visitor
    4643                void mutateDeclarationList(std::list< Declaration* >& decls);
    47 
     44               
    4845                /// Called on entry to a new scope; overriders should call this as a super-class call
    4946                virtual void doBeginScope();
  • src/InitTweak/FixGlobalInit.cc

    rccb447e r31e46b8  
    4646                FunctionDecl * destroyFunction;
    4747        };
     48
     49        class ConstExprChecker : public Visitor {
     50        public:
     51                ConstExprChecker() : isConstExpr( true ) {}
     52
     53                virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
     54                virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
     55                virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
     56                virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
     57                virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
     58                virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
     59                virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
     60                virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
     61                virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
     62                // these might be okay?
     63                // virtual void visit( SizeofExpr *sizeofExpr );
     64                // virtual void visit( AlignofExpr *alignofExpr );
     65                // virtual void visit( UntypedOffsetofExpr *offsetofExpr );
     66                // virtual void visit( OffsetofExpr *offsetofExpr );
     67                // virtual void visit( OffsetPackExpr *offsetPackExpr );
     68                // virtual void visit( AttrExpr *attrExpr );
     69                // virtual void visit( CommaExpr *commaExpr );
     70                // virtual void visit( LogicalExpr *logicalExpr );
     71                // virtual void visit( ConditionalExpr *conditionalExpr );
     72                virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
     73                virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
     74                virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
     75                virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
     76                virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
     77                virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
     78
     79                bool isConstExpr;
     80        };
     81
     82        bool isConstExpr( Initializer * init ) {
     83                if ( init ) {
     84                        ConstExprChecker checker;
     85                        init->accept( checker );
     86                        return checker.isConstExpr;
     87                } // if
     88                // for all intents and purposes, no initializer means const expr
     89                return true;
     90        }
    4891
    4992        void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) {
     
    97140                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
    98141
     142                if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
     143                if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
    99144                // C allows you to initialize objects with constant expressions
    100145                // xxx - this is an optimization. Need to first resolve constructors before we decide
     
    102147                // if ( isConstExpr( objDecl->get_init() ) ) return;
    103148
    104                 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    105                         // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    106                         assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
     149                if ( dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) {
     150                        // xxx - initialize each element of the array
     151                } else {
     152                        // steal initializer from object and attach it to a new temporary
     153                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() );
     154                        objDecl->set_init( NULL );
     155                        initStatements.push_back( new DeclStmt( noLabels, newObj ) );
    107156
    108                         Statement * dtor = ctorInit->get_dtor();
    109                         if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
    110                                 // don't need to call intrinsic dtor, because it does nothing, but
    111                                 // non-intrinsic dtors must be called
    112                                 destroyStatements.push_front( dtor );
    113                                 ctorInit->set_dtor( NULL );
    114                         } // if
    115                         if ( Statement * ctor = ctorInit->get_ctor() ) {
    116                                 initStatements.push_back( ctor );
    117                                 objDecl->set_init( NULL );
    118                                 ctorInit->set_ctor( NULL );
    119                         } else if ( Initializer * init = ctorInit->get_init() ) {
    120                                 objDecl->set_init( init );
    121                                 ctorInit->set_init( NULL );
    122                         } else {
    123                                 // no constructor and no initializer, which is okay
    124                                 objDecl->set_init( NULL );
    125                         } // if
    126                         delete ctorInit;
     157                        // copy construct objDecl using temporary
     158                        UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
     159                        init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     160                        init->get_args().push_back( new VariableExpr( newObj ) );
     161                        initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
     162
     163                        // add destructor calls to global destroy function
     164                        UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
     165                        destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     166                        destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
    127167                } // if
    128168        }
  • src/InitTweak/FixInit.cc

    rccb447e r31e46b8  
    1818#include <iterator>
    1919#include <algorithm>
     20#include "FixInit.h"
    2021#include "InitTweak.h"
    21 #include "FixInit.h"
    22 #include "FixGlobalInit.h"
    2322#include "ResolvExpr/Resolver.h"
    2423#include "ResolvExpr/typeops.h"
     
    8483                };
    8584
    86                 // debug
    8785                struct printSet {
    8886                        typedef ObjDeclCollector::ObjectSet ObjectSet;
     
    173171        } // namespace
    174172
    175         void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
    176                 // fixes ConstructorInit for global variables. should happen before fixInitializers.
    177                 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    178 
     173        void fix( std::list< Declaration * > & translationUnit ) {
    179174                InsertImplicitCalls::insert( translationUnit );
    180175                ResolveCopyCtors::resolveImplicitCalls( translationUnit );
  • src/InitTweak/FixInit.h

    rccb447e r31e46b8  
    2727  /// replace constructor initializers with expression statements
    2828  /// and unwrap basic C-style initializers
    29         void fix( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary );
     29        void fix( std::list< Declaration * > & translationUnit );
    3030} // namespace
    3131
  • src/InitTweak/GenInit.cc

    rccb447e r31e46b8  
    2626#include "SymTab/Autogen.h"
    2727#include "GenPoly/PolyMutator.h"
    28 #include "GenPoly/DeclMutator.h"
    2928
    3029namespace InitTweak {
     
    5655          public:
    5756                /// create constructor and destructor statements for object declarations.
    58                 /// the actual call statements will be added in after the resolver has run
    59                 /// so that the initializer expression is only removed if a constructor is found
    60                 /// and the same destructor call is inserted in all of the appropriate locations.
     57                /// Destructors are inserted directly into the code, whereas constructors
     58                /// will be added in after the resolver has run so that the initializer expression
     59                /// is only removed if a constructor is found
    6160                static void generateCtorDtor( std::list< Declaration * > &translationUnit );
     61
     62                CtorDtor() : inFunction( false ) {}
    6263
    6364                virtual DeclarationWithType * mutate( ObjectDecl * );
    6465                virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    65                 // should not traverse into any of these declarations to find objects
    66                 // that need to be constructed or destructed
    67                 virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
    68                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
    69                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
    70                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
    71                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; }
    72                 virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; }
    73 
    74                 virtual Type * mutate( FunctionType *funcType ) { return funcType; }
     66                virtual Declaration* mutate( StructDecl *aggregateDecl );
     67                virtual Declaration* mutate( UnionDecl *aggregateDecl );
     68                virtual Declaration* mutate( EnumDecl *aggregateDecl );
     69                virtual Declaration* mutate( TraitDecl *aggregateDecl );
     70                virtual TypeDecl* mutate( TypeDecl *typeDecl );
     71                virtual Declaration* mutate( TypedefDecl *typeDecl );
     72
     73                virtual Type * mutate( FunctionType *funcType );
    7574
    7675          protected:
    77         };
    78 
    79         class HoistArrayDimension : public GenPoly::DeclMutator {
    80           public:
    81                 typedef GenPoly::DeclMutator Parent;
    82 
    83                 /// hoist dimension from array types in object declaration so that it uses a single
    84                 /// const variable of type size_t, so that side effecting array dimensions are only
    85                 /// computed once.
    86                 static void hoistArrayDimension( std::list< Declaration * > & translationUnit );
    87 
    88           private:
    89                 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl );
    90                 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl );
    91                 // should not traverse into any of these declarations to find objects
    92                 // that need to be constructed or destructed
    93                 virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
    94                 virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
    95                 virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
    96                 virtual Declaration* mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
    97                 virtual TypeDecl* mutate( TypeDecl *typeDecl ) { return typeDecl; }
    98                 virtual Declaration* mutate( TypedefDecl *typeDecl ) { return typeDecl; }
    99 
    100                 virtual Type* mutate( FunctionType *funcType ) { return funcType; }
    101 
    102                 void hoist( Type * type );
    103 
    104                 DeclarationNode::StorageClass storageclass = DeclarationNode::NoStorageClass;
    105                 bool inFunction = false;
     76                bool inFunction;
    10677        };
    10778
    10879        void genInit( std::list< Declaration * > & translationUnit ) {
    10980                ReturnFixer::makeReturnTemp( translationUnit );
    110                 HoistArrayDimension::hoistArrayDimension( translationUnit );
    11181                CtorDtor::generateCtorDtor( translationUnit );
    11282        }
     
    154124        }
    155125
    156         void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    157                 HoistArrayDimension hoister;
    158                 hoister.mutateDeclarationList( translationUnit );
    159         }
    160 
    161         DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) {
    162                 storageclass = objectDecl->get_storageClass();
    163                 DeclarationWithType * temp = Parent::mutate( objectDecl );
    164                 hoist( objectDecl->get_type() );
    165                 storageclass = DeclarationNode::NoStorageClass;
    166                 return temp;
    167         }
    168 
    169         void HoistArrayDimension::hoist( Type * type ) {
    170                 // if in function, generate const size_t var
    171                 static UniqueName dimensionName( "_array_dim" );
    172                 if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
    173                         if ( ! inFunction ) return;
    174 
    175                         if ( ! arrayType->get_dimension() ) return; // xxx - recursive call to hoist?
    176 
    177                         // don't need to hoist dimension if it's a constexpr - only need to if there's potential
    178                         // for side effects.
    179                         if ( isConstExpr( arrayType->get_dimension() ) ) return;
    180 
    181                         ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageclass, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
    182                         arrayDimension->get_type()->set_isConst( true );
    183 
    184                         arrayType->set_dimension( new VariableExpr( arrayDimension ) );
    185                         addDeclaration( arrayDimension );
    186 
    187                         hoist( arrayType->get_base() );
    188                         return;
    189                 }
    190         }
    191 
    192         DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
    193                 bool oldInFunc = inFunction;
    194                 inFunction = true;
    195                 DeclarationWithType * decl = Parent::mutate( functionDecl );
    196                 inFunction = oldInFunc;
    197                 return decl;
    198         }
    199126
    200127        void CtorDtor::generateCtorDtor( std::list< Declaration * > & translationUnit ) {
     
    213140
    214141        DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
    215                 // hands off if designated, if @=, or if extern
     142                // hands off if designated or if @=
    216143                if ( tryConstruct( objDecl ) ) {
    217                         if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
    218                                 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
    219                                 // TODO: walk initializers and generate appropriate ctor if element has initializer.
    220                                 // Initializer could be nested (depends on the depth of the array type on the object)
    221 
    222                                 std::list< Expression * > args = makeInitList( objDecl->get_init() );
    223                                 if ( args.empty() ) {
    224                                         std::list< Statement * > ctor;
    225                                         std::list< Statement * > dtor;
    226 
    227                                         SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
    228                                         SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
    229 
    230                                         // Currently genImplicitCall produces a single Statement - a CompoundStmt
    231                                         // which  wraps everything that needs to happen. As such, it's technically
    232                                         // possible to use a Statement ** in the above calls, but this is inherently
    233                                         // unsafe, so instead we take the slightly less efficient route, but will be
    234                                         // immediately informed if somehow the above assumption is broken. In this case,
    235                                         // we could always wrap the list of statements at this point with a CompoundStmt,
    236                                         // but it seems reasonable at the moment for this to be done by genImplicitCall
    237                                         // itself. It is possible that genImplicitCall produces no statements (e.g. if
    238                                         // an array type does not have a dimension). In this case, it's fine to ignore
    239                                         // the object for the purposes of construction.
    240                                         assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
    241                                         if ( ctor.size() == 1 ) {
    242                                                 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
     144                        if ( inFunction ) {
     145                                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
     146                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
     147                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
     148                                        std::list< Expression * > args = makeInitList( objDecl->get_init() );
     149                                        if ( args.empty() ) {
     150                                                std::list< Statement * > ctor;
     151                                                std::list< Statement * > dtor;
     152
     153                                                SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     154                                                SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     155
     156                                                // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     157                                                // which  wraps everything that needs to happen. As such, it's technically
     158                                                // possible to use a Statement ** in the above calls, but this is inherently
     159                                                // unsafe, so instead we take the slightly less efficient route, but will be
     160                                                // immediately informed if somehow the above assumption is broken. In this case,
     161                                                // we could always wrap the list of statements at this point with a CompoundStmt,
     162                                                // but it seems reasonable at the moment for this to be done by makeArrayFunction
     163                                                // itself
     164                                                assert( ctor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( ctor.front() ) );
     165                                                assert( dtor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( dtor.front() ) );
    243166                                                objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     167                                        } else {
     168                                                // array came with an initializer list: initialize each element
     169                                                // may have more initializers than elements in the array - need to check at each index that
     170                                                // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
     171                                                // computation.
     172                                                // may have fewer initializers than eleemnts in the array - need to default construct
     173                                                // remaining elements.
     174                                                // might be able to merge this with the case above.
    244175                                        }
    245176                                } else {
    246                                         // array came with an initializer list: initialize each element
    247                                         // may have more initializers than elements in the array - need to check at each index that
    248                                         // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
    249                                         // computation.
    250                                         // may have fewer initializers than elements in the array - need to default construct
    251                                         // remaining elements.
    252                                         // might be able to merge this with the case above.
    253 
     177                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     178                                        Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
     179                                        Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
     180
     181                                        // need to remember init expression, in case no ctors exist
     182                                        // if ctor does exist, want to use ctor expression instead of init
     183                                        // push this decision to the resolver
     184                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
     185                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
     186                                        objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
    254187                                }
    255                         } else {
    256                                 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
    257                                 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) );
    258                                 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() );
    259 
    260                                 // need to remember init expression, in case no ctors exist
    261                                 // if ctor does exist, want to use ctor expression instead of init
    262                                 // push this decision to the resolver
    263                                 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
    264                                 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
    265                                 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
    266188                        }
    267189                }
     
    271193        DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    272194                // parameters should not be constructed and destructed, so don't mutate FunctionType
     195                bool oldInFunc = inFunction;
    273196                mutateAll( functionDecl->get_oldDecls(), *this );
     197                inFunction = true;
    274198                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     199                inFunction = oldInFunc;
    275200                return functionDecl;
    276201        }
     202
     203        // should not traverse into any of these declarations to find objects
     204        // that need to be constructed or destructed
     205        Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     206        Declaration* CtorDtor::mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
     207        Declaration* CtorDtor::mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     208        Declaration* CtorDtor::mutate( TraitDecl *aggregateDecl ) { return aggregateDecl; }
     209        TypeDecl* CtorDtor::mutate( TypeDecl *typeDecl ) { return typeDecl; }
     210        Declaration* CtorDtor::mutate( TypedefDecl *typeDecl ) { return typeDecl; }
     211        Type* CtorDtor::mutate( FunctionType *funcType ) { return funcType; }
     212
    277213} // namespace InitTweak
    278214
  • src/InitTweak/InitTweak.cc

    rccb447e r31e46b8  
    5757                        (objDecl->get_init() == NULL ||
    5858                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
    59                         ! isDesignated( objDecl->get_init() )
    60                         && objDecl->get_storageClass() != DeclarationNode::Extern;
     59                        ! isDesignated( objDecl->get_init() );
    6160        }
    6261
     
    161160                else return NULL;
    162161        }
    163 
    164         class ConstExprChecker : public Visitor {
    165         public:
    166                 ConstExprChecker() : isConstExpr( true ) {}
    167 
    168                 virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
    169                 virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
    170                 virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
    171                 virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
    172                 virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
    173                 virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
    174                 virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
    175                 virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
    176                 virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
    177                 // these might be okay?
    178                 // virtual void visit( SizeofExpr *sizeofExpr );
    179                 // virtual void visit( AlignofExpr *alignofExpr );
    180                 // virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    181                 // virtual void visit( OffsetofExpr *offsetofExpr );
    182                 // virtual void visit( OffsetPackExpr *offsetPackExpr );
    183                 // virtual void visit( AttrExpr *attrExpr );
    184                 // virtual void visit( CommaExpr *commaExpr );
    185                 // virtual void visit( LogicalExpr *logicalExpr );
    186                 // virtual void visit( ConditionalExpr *conditionalExpr );
    187                 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
    188                 virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
    189                 virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
    190                 virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
    191                 virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
    192                 virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
    193 
    194                 bool isConstExpr;
    195         };
    196 
    197         bool isConstExpr( Expression * expr ) {
    198                 if ( expr ) {
    199                         ConstExprChecker checker;
    200                         expr->accept( checker );
    201                         return checker.isConstExpr;
    202                 }
    203                 return true;
    204         }
    205 
    206         bool isConstExpr( Initializer * init ) {
    207                 if ( init ) {
    208                         ConstExprChecker checker;
    209                         init->accept( checker );
    210                         return checker.isConstExpr;
    211                 } // if
    212                 // for all intents and purposes, no initializer means const expr
    213                 return true;
    214         }
    215 
    216162}
  • src/InitTweak/InitTweak.h

    rccb447e r31e46b8  
    2626// helper functions for initialization
    2727namespace InitTweak {
    28         /// transform Initializer into an argument list that can be passed to a call expression
    29         std::list< Expression * > makeInitList( Initializer * init );
     28  /// transform Initializer into an argument list that can be passed to a call expression
     29  std::list< Expression * > makeInitList( Initializer * init );
    3030
    31         /// True if the resolver should try to construct objDecl
    32         bool tryConstruct( ObjectDecl * objDecl );
     31  /// True if the resolver should try to construct objDecl
     32  bool tryConstruct( ObjectDecl * objDecl );
    3333
    34         /// True if the Initializer contains designations
    35         bool isDesignated( Initializer * init );
     34  /// True if the Initializer contains designations
     35  bool isDesignated( Initializer * init );
    3636
    37         /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
    38         /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
    39         /// Currently has assertions that make it less than fully general.
    40         bool isInstrinsicSingleArgCallStmt( Statement * expr );
     37  /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
     38  /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
     39  /// Currently has assertions that make it less than fully general.
     40  bool isInstrinsicSingleArgCallStmt( Statement * expr );
    4141
    42         /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
    43         Expression * getCtorDtorCall( Statement * stmt );
     42  /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
     43  Expression * getCtorDtorCall( Statement * stmt );
    4444
    45         /// returns the name of the function being called
    46         std::string getFunctionName( Expression * expr );
     45  /// returns the name of the function being called
     46  std::string getFunctionName( Expression * expr );
    4747
    48         /// returns the argument to a call expression in position N indexed from 0
    49         Expression *& getCallArg( Expression * callExpr, unsigned int pos );
     48  /// returns the argument to a call expression in position N indexed from 0
     49  Expression *& getCallArg( Expression * callExpr, unsigned int pos );
    5050
    51         /// returns the base type of a PointerType or ArrayType, else returns NULL
    52         Type * getPointerBase( Type * );
     51  /// returns the base type of a PointerType or ArrayType, else returns NULL
     52  Type * getPointerBase( Type * );
    5353
    54         /// returns the argument if it is a PointerType or ArrayType, else returns NULL
    55         Type * isPointerType( Type * );
    56 
    57         /// returns true if expr is trivially a compile-time constant
    58         bool isConstExpr( Expression * expr );
    59         bool isConstExpr( Initializer * init );
     54  /// returns the argument if it is a PointerType or ArrayType, else returns NULL
     55  Type * isPointerType( Type * );
    6056} // namespace
    6157
  • src/ResolvExpr/Resolver.cc

    rccb447e r31e46b8  
    2424#include "SynTree/Initializer.h"
    2525#include "SymTab/Indexer.h"
    26 #include "SymTab/Autogen.h"
    2726#include "Common/utility.h"
    2827#include "InitTweak/InitTweak.h"
     
    4241
    4342                virtual void visit( ArrayType * at );
    44                 virtual void visit( PointerType * at );
    4543
    4644                virtual void visit( ExprStmt *exprStmt );
     
    6159          private:
    6260        typedef std::list< Initializer * >::iterator InitIterator;
    63 
    64                 template< typename PtrType >
    65                 void handlePtrType( PtrType * type );
    6661
    6762          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
     
    197192        }
    198193
    199         template< typename PtrType >
    200         void Resolver::handlePtrType( PtrType * type ) {
    201                 if ( type->get_dimension() ) {
    202                         CastExpr *castExpr = new CastExpr( type->get_dimension(), SymTab::SizeType->clone() );
     194        void Resolver::visit( ArrayType * at ) {
     195                if ( at->get_dimension() ) {
     196                        BasicType arrayLenType = BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     197                        CastExpr *castExpr = new CastExpr( at->get_dimension(), arrayLenType.clone() );
    203198                        Expression *newExpr = findSingleExpression( castExpr, *this );
    204                         delete type->get_dimension();
    205                         type->set_dimension( newExpr );
    206                 }
    207         }
    208 
    209         void Resolver::visit( ArrayType * at ) {
    210                 handlePtrType( at );
     199                        delete at->get_dimension();
     200                        at->set_dimension( newExpr );
     201                }
    211202                Visitor::visit( at );
    212         }
    213 
    214         void Resolver::visit( PointerType * pt ) {
    215                 handlePtrType( pt );
    216                 Visitor::visit( pt );
    217203        }
    218204
     
    551537                assert( callExpr );
    552538                Expression *& constructee = InitTweak::getCallArg( callExpr, 0 );
    553 
    554                 // the first argument will always be &<expr>
    555                 AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
    556                 assert( addrExpr );
    557 
    558                 // need to find the type of the first argument. In the case of an array,
    559                 // need to remove one ArrayType layer from the type for each subscript expression.
    560                 Expression * addressee = addrExpr->get_arg();
    561                 int numLayers = 0;
    562                 while ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( addressee ) ) {
    563                         assert( InitTweak::getFunctionName( untypedExpr ) == "?[?]" );
    564                         addressee = InitTweak::getCallArg( untypedExpr, 0 );
    565                         numLayers++;
    566                 }
    567                 assert( addressee->get_results().size() == 1 );
    568                 Type * type = addressee->get_results().front();
    569                 for ( int i = 0; i < numLayers; i++ ) {
    570                         type = InitTweak::getPointerBase( type );
    571                         assert( type && "Expected pointer or array type. May have generated too many ?[?] calls." );
    572                 }
    573 
     539                Type * type = 0;
     540
     541                // need to find the type of the first argument, which is unfortunately not uniform since array construction
     542                // includes an untyped '+' expression.
     543                if ( UntypedExpr * plusExpr = dynamic_cast< UntypedExpr * >( constructee ) ) {
     544                        // constructee is <array>+<index>
     545                        // get Variable <array>, then get the base type of the VariableExpr - this is the type that needs to be fixed
     546                        Expression * arr = InitTweak::getCallArg( plusExpr, 0 );
     547                        assert( dynamic_cast< VariableExpr * >( arr ) || dynamic_cast< MemberExpr *>( arr ) );
     548                        assert( arr && arr->get_results().size() == 1 );
     549                        type = arr->get_results().front()->clone();
     550                } else {
     551                        // otherwise, constructing a plain object, which means the object's address is being taken.
     552                        // Need to get the type of the VariableExpr object, because the AddressExpr is rebuilt and uses the
     553                        // type of the VariableExpr to do so.
     554                        assert( constructee->get_results().size() == 1 );
     555                        AddressExpr * addrExpr = dynamic_cast< AddressExpr * > ( constructee );
     556                        assert( addrExpr && addrExpr->get_results().size() == 1 );
     557                        type = addrExpr->get_results().front()->clone();
     558                }
    574559                // cast to T* with qualifiers removed.
    575560                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     
    577562                // remove lvalue as a qualifier, this can change to
    578563                //   type->get_qualifiers() = Type::Qualifiers();
    579                 assert( type );
    580                 type = type->clone();
    581                 type->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
    582                 type = new PointerType( Type::Qualifiers(), type );
     564                Type * base = InitTweak::getPointerBase( type );
     565                assert( base );
     566                base->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true);
     567                // if pointer has lvalue qualifier, cast won't appear in output
     568                type->set_isLvalue( false );
    583569                constructee = new CastExpr( constructee, type );
    584570
  • src/SymTab/Autogen.cc

    rccb447e r31e46b8  
    2626
    2727namespace SymTab {
    28         Type * SizeType = 0;
    29 
    3028        class AutogenerateRoutines : public Visitor {
    3129                public:
     
    6159        bool isUnnamedBitfield( ObjectDecl * obj ) {
    6260                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;
    6393        }
    6494
     
    190220
    191221                // assign to destination (and return value if generic)
    192                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    193                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    194                 Expression *dstselect = new MemberExpr( field, derefExpr );
    195                 genImplicitCall( src, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    196 
    197                 if ( isGeneric && returnVal ) {
    198                         UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
    199                         derefRet->get_args().push_back( new VariableExpr( returnVal ) );
    200                         Expression *retselect = new MemberExpr( field, derefRet );
    201                         genImplicitCall( src, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     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 ( isGeneric && 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 ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    202238                } // if
    203239        }
  • src/SymTab/Autogen.h

    rccb447e r31e46b8  
    2424
    2525namespace SymTab {
    26         /// Generates assignment operators, constructors, and destructor for aggregate types as required
    27         void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     26  /// Generates assignment operators, constructors, and destructor for aggregate types as required
     27  void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    2828
    29         /// returns true if obj's name is the empty string and it has a bitfield width
    30         bool isUnnamedBitfield( ObjectDecl * obj );
     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
    3131
    32         /// size_t type - set when size_t typedef is seen. Useful in a few places,
    33         /// such as in determining array dimension type
    34         extern Type * SizeType;
     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" );
    3537
    36         /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    37         template< typename OutputIterator >
    38         void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward = true );
     38    // for a flexible array member nothing is done -- user must define own assignment
     39    if ( ! array->get_dimension() ) return;
    3940
    40         /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    41         template< typename OutputIterator >
    42         void genScalarCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out ) {
    43                 // want to be able to generate assignment, ctor, and dtor generically,
    44                 // so fname is either ?=?, ?{}, or ^?{}
    45                 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
     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    }
    4657
    47                 // do something special for unnamed members
    48                 fExpr->get_args().push_back( new AddressExpr( dstParam ) );
     58    ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
    4959
    50                 if ( srcParam ) {
    51                         fExpr->get_args().push_back( srcParam );
    52                 }
     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*>() ) );
    5364
    54                 *out++ = new ExprStmt( noLabels, fExpr );
    55         }
     65    UntypedExpr *cond = new UntypedExpr( cmp );
     66    cond->get_args().push_back( new VariableExpr( index ) );
     67    cond->get_args().push_back( end );
    5668
    57         /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    58         /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    59         template< typename OutputIterator >
    60         void genArrayCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool forward = true ) {
    61                 static UniqueName indexName( "_index" );
     69    UntypedExpr *inc = new UntypedExpr( update );
     70    inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    6271
    63                 // for a flexible array member nothing is done -- user must define own assignment
    64                 if ( ! array->get_dimension() ) return ;
     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 ) );
    6575
    66                 Expression * begin, * end, * update, * cmp;
    67                 if ( forward ) {
    68                         // generate: for ( int i = 0; i < 0; ++i )
    69                         begin = new NameExpr( "0" );
    70                         end = array->get_dimension()->clone();
    71                         cmp = new NameExpr( "?<?" );
    72                         update = new NameExpr( "++?" );
    73                 } else {
    74                         // generate: for ( int i = N-1; i >= 0; --i )
    75                         begin = new UntypedExpr( new NameExpr( "?-?" ) );
    76                         ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    77                         ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) );
    78                         end = new NameExpr( "0" );
    79                         cmp = new NameExpr( "?>=?" );
    80                         update = new NameExpr( "--?" );
    81                 }
     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 );
    8280
    83                 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
     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    }
    8488
    85                 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    86                 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    87                 init->get_args().push_back( begin );
    88                 index->set_init( new SingleInit( init, std::list<Expression*>() ) );
     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 ) ) );
    8993
    90                 UntypedExpr *cond = new UntypedExpr( cmp );
    91                 cond->get_args().push_back( new VariableExpr( index ) );
    92                 cond->get_args().push_back( end );
    93 
    94                 UntypedExpr *inc = new UntypedExpr( update );
    95                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    96 
    97                 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    98                 dstIndex->get_args().push_back( dstParam );
    99                 dstIndex->get_args().push_back( new VariableExpr( index ) );
    100                 dstParam = dstIndex;
    101 
    102                 // srcParam is NULL for default ctor/dtor
    103                 if ( srcParam ) {
    104                         UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    105                         srcIndex->get_args().push_back( srcParam );
    106                         srcIndex->get_args().push_back( new VariableExpr( index ) );
    107                         srcParam = srcIndex;
    108                 }
    109 
    110                 // for stmt's body, eventually containing call
    111                 CompoundStmt * body = new CompoundStmt( noLabels );
    112                 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), forward );
    113 
    114                 // block containing for stmt and index variable
    115                 std::list<Statement *> initList;
    116                 CompoundStmt * block = new CompoundStmt( noLabels );
    117                 block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    118                 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
    119 
    120                 *out++ = block;
    121         }
    122 
    123         template< typename OutputIterator >
    124         void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward ) {
    125                 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    126                         genArrayCall( srcParam, dstParam, fname, out, at, forward );
    127                 } else {
    128                         genScalarCall( srcParam, dstParam, fname, out );
    129                 }
    130         }
    131 
    132         /// inserts into out a generated call expression to function fname with arguments dstParam
    133         /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
    134         /// object being constructed. The function wraps constructor and destructor calls in an
    135         /// ImplicitCtorDtorStmt node.
    136         template< typename OutputIterator >
    137         void genImplicitCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    138                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    139                 assert( obj );
    140                 // unnamed bit fields are not copied as they cannot be accessed
    141                 if ( isUnnamedBitfield( obj ) ) return;
    142 
    143                 std::list< Statement * > stmts;
    144                 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), forward );
    145 
    146                 // 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
    147                 assert( stmts.size() <= 1 );
    148     if ( stmts.size() == 1 ) {
    149                 Statement * callStmt = stmts.front();
    150                 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {
    151                         // implicitly generated ctor/dtor calls should be wrapped
    152                         // so that later passes are aware they were generated.
    153                         // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    154                         // because this causes the address to be taken at codegen, which is illegal in C.
    155                         callStmt = new ImplicitCtorDtorStmt( callStmt );
    156                 }
    157                 *out++ = callStmt;
     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 );
    15899    }
    159         }
     100    *out++ = stmt;
     101  }
    160102} // namespace SymTab
    161103#endif // AUTOGEN_H
  • src/SymTab/FixFunction.cc

    rccb447e r31e46b8  
    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                 // 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() );
     46                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
    4847                delete arrayType;
    4948                return pointerType;
  • src/SymTab/Validate.cc

    rccb447e r31e46b8  
    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
    194193                acceptAll( translationUnit, pass1 );
    195194                acceptAll( translationUnit, pass2 );
    196195                ReturnChecker::checkFunctionReturns( translationUnit );
    197                 compoundliteral.mutateDeclarationList( translationUnit );
     196                mutateAll( translationUnit, compoundliteral );
     197                autogenerateRoutines( 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                 }
    500492                filter( translationUnit, isTypedef, true );
    501 
    502493        }
    503494
     
    527518        Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) {
    528519                Declaration *ret = Mutator::mutate( tyDecl );
    529 
    530520                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    531521                        // typedef to the same name from the same scope
  • src/main.cc

    rccb447e r31e46b8  
    4242#include "InitTweak/GenInit.h"
    4343#include "InitTweak/FixInit.h"
     44#include "InitTweak/FixGlobalInit.h"
    4445//#include "Explain/GenProlog.h"
    4546//#include "Try/Visit.h"
     
    281282                OPTPRINT( "fixNames" )
    282283                CodeGen::fixNames( translationUnit );
     284                OPTPRINT( "fixGlobalInit" );
     285                InitTweak::fixGlobalInit( translationUnit, filename, libcfap || treep );
    283286                OPTPRINT( "tweakInit" )
    284287                InitTweak::genInit( translationUnit );
     
    301304                }
    302305
     306                OPTPRINT( "fixInit" )
    303307                // fix ObjectDecl - replaces ConstructorInit nodes
    304                 OPTPRINT( "fixInit" )
    305                 InitTweak::fix( translationUnit, filename, libcfap || treep );
     308                InitTweak::fix( translationUnit );
    306309                if ( ctorinitp ) {
    307310                        dump ( translationUnit );
  • src/tests/.expect/64/extension.txt

    rccb447e r31e46b8  
    100100    ((void)((__extension__ __a__i_2 , __extension__ __b__i_2) , __extension__ __c__i_2));
    101101}
     102__attribute__ ((constructor(),)) static void _init_extension(void){
     103    int _global_init0;
     104    ((void)((*((int *)(&__a__i_1)))=_global_init0) /* ?{} */);
     105    int _global_init1;
     106    ((void)((*((int *)(&__b__i_1)))=_global_init1) /* ?{} */);
     107    int _global_init2;
     108    ((void)((*((int *)(&__c__i_1)))=_global_init2) /* ?{} */);
     109}
     110__attribute__ ((destructor(),)) static void _destroy_extension(void){
     111    ((void)((*((int *)(&__c__i_1)))) /* ^?{} */);
     112    ((void)((*((int *)(&__b__i_1)))) /* ^?{} */);
     113    ((void)((*((int *)(&__a__i_1)))) /* ^?{} */);
     114}
Note: See TracChangeset for help on using the changeset viewer.