Changeset 4e24610


Ignore:
Timestamp:
May 6, 2016, 1:56:08 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
d029162
Parents:
711eee5
Message:

Add constructor attribute to global initializer function, don't try to fix const globals, add Constructor/Destructor? attributes to FunctionDecl?

Location:
src
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r711eee5 r4e24610  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.cc -- 
     7// CodeGenerator.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:32:16 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 06 11:39:01 2016
    1313// Update Count     : 243
    1414//
     
    8484                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
    8585
     86                // generalize this
     87                switch ( functionDecl->get_attribute() ) {
     88                        case FunctionDecl::Constructor:
     89                                output << " __attribute__ ((constructor))";
     90                                break;
     91                        case FunctionDecl::Destructor:
     92                                output << " __attribute__ ((destructor))";
     93                                break;
     94                        default:
     95                                break;
     96                }
     97
    8698                // how to get this to the Functype?
    8799                std::list< Declaration * > olds = functionDecl->get_oldDecls();
     
    99111                handleStorageClass( objectDecl );
    100112                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    101        
     113
    102114                if ( objectDecl->get_init() ) {
    103115                        output << " = ";
     
    113125                if ( aggDecl->get_name() != "" )
    114126                        output << aggDecl->get_name();
    115        
     127
    116128                std::list< Declaration * > &memb = aggDecl->get_members();
    117129
     
    119131                        output << " {" << endl;
    120132
    121                         cur_indent += CodeGenerator::tabsize; 
     133                        cur_indent += CodeGenerator::tabsize;
    122134                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    123                                 output << indent; 
     135                                output << indent;
    124136                                (*i)->accept( *this );
    125137                                output << ";" << endl;
    126138                        }
    127139
    128                         cur_indent -= CodeGenerator::tabsize; 
     140                        cur_indent -= CodeGenerator::tabsize;
    129141
    130142                        output << indent << "}";
     
    141153                handleAggregate( aggregateDecl );
    142154        }
    143  
     155
    144156        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    145157                output << "enum ";
     
    147159                if ( aggDecl->get_name() != "" )
    148160                        output << aggDecl->get_name();
    149        
     161
    150162                std::list< Declaration* > &memb = aggDecl->get_members();
    151163
     
    153165                        output << " {" << endl;
    154166
    155                         cur_indent += CodeGenerator::tabsize; 
     167                        cur_indent += CodeGenerator::tabsize;
    156168                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    157169                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    158170                                assert( obj );
    159                                 output << indent << mangleName( obj ); 
     171                                output << indent << mangleName( obj );
    160172                                if ( obj->get_init() ) {
    161173                                        output << " = ";
     
    165177                        } // for
    166178
    167                         cur_indent -= CodeGenerator::tabsize; 
     179                        cur_indent -= CodeGenerator::tabsize;
    168180
    169181                        output << indent << "}";
    170182                } // if
    171183        }
    172  
     184
    173185        void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
    174  
     186
    175187        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    176188                output << "typedef ";
    177189                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    178190        }
    179  
     191
    180192        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    181193                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    217229        }
    218230
    219         void CodeGenerator::visit( Constant *constant ) { 
     231        void CodeGenerator::visit( Constant *constant ) {
    220232                output << constant->get_value() ;
    221233        }
     
    234246                                                assert( arg != applicationExpr->get_args().end() );
    235247                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     248
    237249                                                        *arg = addrExpr->get_arg();
    238250                                                } else {
     
    243255                                                break;
    244256                                        }
    245              
     257
    246258                                  default:
    247259                                        // do nothing
    248260                                        ;
    249261                                }
    250            
     262
    251263                                switch ( opInfo.type ) {
    252264                                  case OT_INDEX:
     
    257269                                        output << "]";
    258270                                        break;
    259              
     271
    260272                                  case OT_CALL:
    261273                                        // there are no intrinsic definitions of the function call operator
    262274                                        assert( false );
    263275                                        break;
    264              
     276
    265277                                  case OT_PREFIX:
    266278                                  case OT_PREFIXASSIGN:
     
    271283                                        output << ")";
    272284                                        break;
    273              
     285
    274286                                  case OT_POSTFIX:
    275287                                  case OT_POSTFIXASSIGN:
     
    288300                                        output << ")";
    289301                                        break;
    290              
     302
    291303                                  case OT_CONSTANT:
    292304                                  case OT_LABELADDRESS:
     
    307319                } // if
    308320        }
    309  
     321
    310322        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    311323                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    321333                                        output << "]";
    322334                                        break;
    323              
     335
    324336                                  case OT_CALL:
    325337                                        assert( false );
    326338                                        break;
    327              
     339
    328340                                  case OT_PREFIX:
    329341                                  case OT_PREFIXASSIGN:
     
    335347                                        output << ")";
    336348                                        break;
    337              
     349
    338350                                  case OT_POSTFIX:
    339351                                  case OT_POSTFIXASSIGN:
     
    342354                                        output << opInfo.symbol;
    343355                                        break;
    344  
     356
    345357                                  case OT_INFIX:
    346358                                  case OT_INFIXASSIGN:
     
    352364                                        output << ")";
    353365                                        break;
    354                                        
     366
    355367                                  case OT_CONSTANT:
    356368                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370382                } // if
    371383        }
    372  
     384
    373385        void CodeGenerator::visit( NameExpr *nameExpr ) {
    374386                OperatorInfo opInfo;
     
    380392                } // if
    381393        }
    382  
     394
    383395        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    384396                output << "(&";
     
    409421                output << ")";
    410422        }
    411  
     423
    412424        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413425                assert( false );
    414426        }
    415  
     427
    416428        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    417429                memberExpr->get_aggregate()->accept( *this );
    418430                output << "." << mangleName( memberExpr->get_member() );
    419431        }
    420  
     432
    421433        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    422434                OperatorInfo opInfo;
     
    427439                } // if
    428440        }
    429  
     441
    430442        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431443                assert( constantExpr->get_constant() );
    432444                constantExpr->get_constant()->accept( *this );
    433445        }
    434  
     446
    435447        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    436448                output << "sizeof(";
     
    469481                assert( false && "OffsetPackExpr should not reach code generation" );
    470482        }
    471  
     483
    472484        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    473485                output << "(";
     
    481493                output << ")";
    482494        }
    483  
     495
    484496        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    485497                output << "(";
     
    491503                output << ")";
    492504        }
    493  
     505
    494506        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    495507                output << "(";
     
    499511                output << ")";
    500512        }
    501  
     513
    502514        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    503  
     515
    504516        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    505517
     
    532544                        }
    533545                }
    534                 cur_indent -= CodeGenerator::tabsize; 
     546                cur_indent -= CodeGenerator::tabsize;
    535547
    536548                output << indent << "}";
     
    538550
    539551        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    540                 // I don't see why this check is necessary. 
    541                 // If this starts to cause problems then put it back in, 
     552                // I don't see why this check is necessary.
     553                // If this starts to cause problems then put it back in,
    542554                // with an explanation
    543555                assert( exprStmt );
     
    589601                switchStmt->get_condition()->accept( *this );
    590602                output << " ) ";
    591                
     603
    592604                output << "{" << std::endl;
    593605                cur_indent += CodeGenerator::tabsize;
     
    609621                } // if
    610622                output << ":\n";
    611                
     623
    612624                std::list<Statement *> sts = caseStmt->get_statements();
    613625
     
    626638                        if ( ! branchStmt->get_target().empty() )
    627639                                output << "goto " << branchStmt->get_target();
    628                         else { 
     640                        else {
    629641                                if ( branchStmt->get_computedTarget() != 0 ) {
    630642                                        output << "goto *";
     
    677689
    678690        void CodeGenerator::visit( ForStmt *forStmt ) {
    679                 // initialization is always hoisted, so don't 
    680                 // bother doing anything with that 
     691                // initialization is always hoisted, so don't
     692                // bother doing anything with that
    681693                output << "for (;";
    682694
     
    702714        void CodeGenerator::visit( DeclStmt *declStmt ) {
    703715                declStmt->get_decl()->accept( *this );
    704        
     716
    705717                if ( doSemicolon( declStmt->get_decl() ) ) {
    706718                        output << ";";
  • src/InitTweak/FixGlobalInit.cc

    r711eee5 r4e24610  
    1010// Created On       : Mon May 04 15:14:56 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 04 16:53:12 2016
     12// Last Modified On : Fri May 06 13:51:00 2016
    1313// Update Count     : 2
    1414//
     
    3030        class GlobalFixer : public Visitor {
    3131          public:
    32                 GlobalFixer( const std::string & fileName );
     32                GlobalFixer();
    3333
    3434                virtual void visit( ObjectDecl *objDecl );
    3535                virtual void visit( FunctionDecl *functionDecl );
     36                virtual void visit( StructDecl *aggregateDecl );
     37                virtual void visit( UnionDecl *aggregateDecl );
     38                virtual void visit( EnumDecl *aggregateDecl );
     39                virtual void visit( TraitDecl *aggregateDecl );
     40                virtual void visit( TypeDecl *typeDecl );
    3641
    3742                UniqueName tempNamer;
    38                 FunctionDecl * initFunction;
     43                CompoundStmt * block;
    3944        };
    4045
     
    8388
    8489        void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name ) {
    85                 GlobalFixer fixer( name );
     90                GlobalFixer fixer;
    8691                acceptAll( translationUnit, fixer );
    87                 translationUnit.push_back( fixer.initFunction );
     92                // attribute only appears on the forward declaration, so need to make two function decls:
     93                // one with the body, one with the attribute.
     94                FunctionDecl * initFunction = new FunctionDecl( initName( name ), DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), 0, false, false );
     95                FunctionDecl * forward = initFunction->clone();
     96                forward->set_attribute( FunctionDecl::Constructor );
     97                initFunction->set_statements( fixer.block );
     98                translationUnit.push_back( forward );
     99                translationUnit.push_back( initFunction );
    88100        }
    89101
     
    97109  }
    98110
    99         GlobalFixer::GlobalFixer( const std::string & fileName ) : tempNamer( "_global_init" ) {
    100                 initFunction = new FunctionDecl( initName( fileName ), DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
     111        GlobalFixer::GlobalFixer() : tempNamer( "_global_init" ), block( new CompoundStmt( noLabels ) ) {
    101112        }
    102113
    103114        void GlobalFixer::visit( ObjectDecl *objDecl ) {
    104                 std::list< Statement * > & statements = initFunction->get_statements()->get_kids();
     115                std::list< Statement * > & statements = block->get_kids();
    105116
     117                if ( objDecl->get_init() == NULL ) return;
     118                if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable
    106119                // C allows you to initialize objects with constant expressions
    107                 if ( isConstExpr( objDecl->get_init() ) ) return;
     120                // xxx - this is an optimization. Need to first resolve constructors before we decide
     121                // to keep C-style initializer.
     122                // if ( isConstExpr( objDecl->get_init() ) ) return;
    108123
    109124                // steal initializer from object and attach it to a new temporary
     
    121136        }
    122137
    123         void GlobalFixer::visit( FunctionDecl *functionDecl ) {
    124                 // only modify global variables
    125         }
     138        // only modify global variables
     139        void GlobalFixer::visit( FunctionDecl *functionDecl ) {}
     140        void GlobalFixer::visit( StructDecl *aggregateDecl ) {}
     141        void GlobalFixer::visit( UnionDecl *aggregateDecl ) {}
     142        void GlobalFixer::visit( EnumDecl *aggregateDecl ) {}
     143        void GlobalFixer::visit( TraitDecl *aggregateDecl ) {}
     144        void GlobalFixer::visit( TypeDecl *typeDecl ) {}
     145
    126146} // namespace InitTweak
    127147
  • src/SynTree/Declaration.h

    r711eee5 r4e24610  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Declaration.h -- 
     7// Declaration.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:28:11 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 06 11:16:45 2016
    1313// Update Count     : 33
    1414//
     
    106106        typedef DeclarationWithType Parent;
    107107  public:
    108         FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn );
     108        // temporary - merge this into general GCC attributes
     109        enum Attribute {
     110                NoAttribute, Constructor, Destructor,
     111        };
     112
     113        FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute = NoAttribute );
    109114        FunctionDecl( const FunctionDecl &other );
    110115        virtual ~FunctionDecl();
     
    119124        std::list< std::string >& get_oldIdents() { return oldIdents; }
    120125        std::list< Declaration* >& get_oldDecls() { return oldDecls; }
     126        Attribute get_attribute() const { return attribute; }
     127        void set_attribute( Attribute newValue ) { attribute = newValue; }
    121128
    122129        virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
     
    130137        std::list< std::string > oldIdents;
    131138        std::list< Declaration* > oldDecls;
     139        Attribute attribute;
    132140};
    133141
  • src/SynTree/FunctionDecl.cc

    r711eee5 r4e24610  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Apr 01 11:40:07 2016
     12// Last Modified On : Fri May 06 11:35:09 2016
    1313// Update Count     : 19
    1414//
     
    2121#include "Common/utility.h"
    2222
    23 FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn )
    24                 : Parent( name, sc, linkage ), type( type ), statements( statements ) {
     23FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute )
     24                : Parent( name, sc, linkage ), type( type ), statements( statements ), attribute( attribute ) {
    2525        set_isInline( isInline );
    2626        set_isNoreturn( isNoreturn );
     27        // this is a brazen hack to force the function "main" to have C linkage
     28        if ( name == "main" ) {
     29                set_linkage( LinkageSpec::C );
     30        } // if
    2731}
    2832
    2933FunctionDecl::FunctionDecl( const FunctionDecl &other )
    30         : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {
     34        : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), attribute( other.attribute ) {
    3135}
    3236
     
    6165                os << "_Noreturn ";
    6266        } // if
     67        switch ( attribute ) {
     68                case Constructor:
     69                        os << "Global Constructor ";
     70                        break;
     71                case Destructor:
     72                        os << "Global Destructor ";
     73                        break;
     74                default:
     75                        break;
     76        }
    6377        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    6478                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
     
    100114                os << "_Noreturn ";
    101115        } // if
     116        switch ( attribute ) {
     117                case Constructor:
     118                        os << " Global Constructor ";
     119                        break;
     120                case Destructor:
     121                        os << " Global Destructor ";
     122                        break;
     123                default:
     124                        break;
     125        }
    102126        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    103127                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
Note: See TracChangeset for help on using the changeset viewer.