Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.h

    rd180746 r1a5ad8c  
    1919#include <string>                 // for string
    2020
     21#include "CodeGen/OperatorTable.h"
    2122#include "Common/UniqueName.h"    // for UniqueName
    2223#include "InitTweak/InitTweak.h"  // for InitExpander
     
    4041        extern Type * SizeType;
    4142
     43        /// intrinsic dereference operator for unqualified types - set when *? function is seen in FindSpecialDeclarations.
     44        /// Useful for creating dereference ApplicationExprs without a full resolver pass.
     45        extern FunctionDecl * dereferenceOperator;
     46
     47        // generate the type of an assignment function for paramType
     48        FunctionType * genAssignType( Type * paramType );
     49
     50        // generate the type of a default constructor or destructor for paramType
     51        FunctionType * genDefaultType( Type * paramType );
     52
     53        // generate the type of a copy constructor for paramType
     54        FunctionType * genCopyType( Type * paramType );
     55
    4256        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    4357        template< typename OutputIterator >
     
    4761        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    4862        template< typename OutputIterator >
    49         Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    50         // want to be able to generate assignment, ctor, and dtor generically,
    51         // so fname is either ?=?, ?{}, or ^?{}
    52         UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    53 
    54         // do something special for unnamed members
    55         dstParam = new AddressExpr( dstParam );
    56         if ( addCast ) {
    57                 // cast to T* with qualifiers removed, so that qualified objects can be constructed
    58                 // and destructed with the same functions as non-qualified objects.
    59                 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
    60                 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
    61                 // remove lvalue as a qualifier, this can change to
    62                 //   type->get_qualifiers() = Type::Qualifiers();
    63                 assert( type );
    64                 Type * castType = type->clone();
    65                 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    66                 castType->set_lvalue( true ); // xxx - might not need this
    67                 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    68         }
    69         fExpr->get_args().push_back( dstParam );
    70 
    71         Statement * listInit = srcParam.buildListInit( fExpr );
    72 
    73         std::list< Expression * > args = *++srcParam;
    74         fExpr->get_args().splice( fExpr->get_args().end(), args );
    75 
    76         *out++ = new ExprStmt( noLabels, fExpr );
    77 
    78         srcParam.clearArrayIndices();
    79 
    80         return listInit;
     63        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false ) {
     64                bool isReferenceCtorDtor = false;
     65                if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     66                        // reference constructors are essentially application of the rebind operator.
     67                        // apply & to both arguments, do not need a cast
     68                        fname = "?=?";
     69                        dstParam = new AddressExpr( dstParam );
     70                        addCast = false;
     71                        isReferenceCtorDtor = true;
     72                }
     73
     74                // want to be able to generate assignment, ctor, and dtor generically,
     75                // so fname is either ?=?, ?{}, or ^?{}
     76                UntypedExpr * fExpr = new UntypedExpr( new NameExpr( fname ) );
     77
     78                if ( addCast ) {
     79                        // cast to T& with qualifiers removed, so that qualified objects can be constructed
     80                        // and destructed with the same functions as non-qualified objects.
     81                        // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     82                        // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     83                        // remove lvalue as a qualifier, this can change to
     84                        //   type->get_qualifiers() = Type::Qualifiers();
     85                        assert( type );
     86                        Type * castType = type->clone();
     87                        castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     88                        // castType->set_lvalue( true ); // xxx - might not need this
     89                        dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) );
     90                }
     91                fExpr->args.push_back( dstParam );
     92
     93                Statement * listInit = srcParam.buildListInit( fExpr );
     94
     95                // fetch next set of arguments
     96                ++srcParam;
     97
     98                // return if adding reference fails - will happen on default constructor and destructor
     99                if ( isReferenceCtorDtor && ! srcParam.addReference() ) {
     100                        delete fExpr;
     101                        return listInit;
     102                }
     103
     104                std::list< Expression * > args = *srcParam;
     105                fExpr->args.splice( fExpr->args.end(), args );
     106
     107                *out++ = new ExprStmt( noLabels, fExpr );
     108
     109                srcParam.clearArrayIndices();
     110
     111                return listInit;
    81112        }
    82113
     
    94125                        // generate: for ( int i = 0; i < N; ++i )
    95126                        begin = new ConstantExpr( Constant::from_int( 0 ) );
    96                         end = array->get_dimension()->clone();
     127                        end = array->dimension->clone();
    97128                        cmp = new NameExpr( "?<?" );
    98129                        update = new NameExpr( "++?" );
     
    100131                        // generate: for ( int i = N-1; i >= 0; --i )
    101132                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
    102                         ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    103                         ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     133                        ((UntypedExpr*)begin)->args.push_back( array->dimension->clone() );
     134                        ((UntypedExpr*)begin)->args.push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
    104135                        end = new ConstantExpr( Constant::from_int( 0 ) );
    105136                        cmp = new NameExpr( "?>=?" );
     
    110141
    111142                UntypedExpr *cond = new UntypedExpr( cmp );
    112                 cond->get_args().push_back( new VariableExpr( index ) );
    113                 cond->get_args().push_back( end );
     143                cond->args.push_back( new VariableExpr( index ) );
     144                cond->args.push_back( end );
    114145
    115146                UntypedExpr *inc = new UntypedExpr( update );
    116                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     147                inc->args.push_back( new VariableExpr( index ) );
    117148
    118149                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    119                 dstIndex->get_args().push_back( dstParam );
    120                 dstIndex->get_args().push_back( new VariableExpr( index ) );
     150                dstIndex->args.push_back( dstParam );
     151                dstIndex->args.push_back( new VariableExpr( index ) );
    121152                dstParam = dstIndex;
    122153
    123154                // srcParam must keep track of the array indices to build the
    124155                // source parameter and/or array list initializer
    125                 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
     156                srcParam.addArrayIndex( new VariableExpr( index ), array->dimension->clone() );
    126157
    127158                // for stmt's body, eventually containing call
    128159                CompoundStmt * body = new CompoundStmt( noLabels );
    129                 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     160                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->kids ), array->base, addCast, forward );
    130161
    131162                // block containing for stmt and index variable
    132163                std::list<Statement *> initList;
    133164                CompoundStmt * block = new CompoundStmt( noLabels );
    134                 block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     165                block->push_back( new DeclStmt( noLabels, index ) );
    135166                if ( listInit ) block->get_kids().push_back( listInit );
    136                 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     167                block->push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
    137168
    138169                *out++ = block;
     
    140171
    141172        template< typename OutputIterator >
    142         Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
     173        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    143174                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    144175                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     
    154185        /// ImplicitCtorDtorStmt node.
    155186        template< typename OutputIterator >
    156         void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     187        void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    157188                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    158189                assert( obj );
     
    162193                bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) );
    163194                std::list< Statement * > stmts;
    164                 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
     195                genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward );
    165196
    166197                // 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
Note: See TracChangeset for help on using the changeset viewer.