Changeset 67fa9f9 for src/SymTab


Ignore:
Timestamp:
Jul 5, 2017, 10:50:22 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
0614d14
Parents:
11dbfe1 (diff), 307a732 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/SymTab
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.h

    r11dbfe1 r67fa9f9  
    2525
    2626namespace SymTab {
    27     /// Generates assignment operators, constructors, and destructor for aggregate types as required
    28     void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     27        /// Generates assignment operators, constructors, and destructor for aggregate types as required
     28        void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    2929
    30     /// returns true if obj's name is the empty string and it has a bitfield width
    31     bool isUnnamedBitfield( ObjectDecl * obj );
     30        /// returns true if obj's name is the empty string and it has a bitfield width
     31        bool isUnnamedBitfield( ObjectDecl * obj );
    3232
    33     /// size_t type - set when size_t typedef is seen. Useful in a few places,
    34     /// such as in determining array dimension type
    35     extern Type * SizeType;
     33        /// size_t type - set when size_t typedef is seen. Useful in a few places,
     34        /// such as in determining array dimension type
     35        extern Type * SizeType;
    3636
    37     /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    38     template< typename OutputIterator >
     37        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
     38        template< typename OutputIterator >
    3939        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
    4040
    41     /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    42     /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    43     template< typename OutputIterator >
     41        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
     42        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
     43        template< typename OutputIterator >
    4444        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    4545        // want to be able to generate assignment, ctor, and dtor generically,
     
    5050        dstParam = new AddressExpr( dstParam );
    5151        if ( addCast ) {
    52             // cast to T* with qualifiers removed, so that qualified objects can be constructed
    53             // and destructed with the same functions as non-qualified objects.
    54             // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
    55             // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
    56             // remove lvalue as a qualifier, this can change to
    57             //   type->get_qualifiers() = Type::Qualifiers();
    58             assert( type );
    59             Type * castType = type->clone();
    60 //                      castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
    61             castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    62             castType->set_lvalue( true ); // xxx - might not need this
    63             dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
     52                // cast to T* with qualifiers removed, so that qualified objects can be constructed
     53                // and destructed with the same functions as non-qualified objects.
     54                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     55                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     56                // remove lvalue as a qualifier, this can change to
     57                //   type->get_qualifiers() = Type::Qualifiers();
     58                assert( type );
     59                Type * castType = type->clone();
     60                castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     61                castType->set_lvalue( true ); // xxx - might not need this
     62                dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    6463        }
    6564        fExpr->get_args().push_back( dstParam );
     
    7574
    7675        return listInit;
    77     }
    78 
    79     /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    80     /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    81     template< typename OutputIterator >
    82         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
    83         static UniqueName indexName( "_index" );
    84 
    85         // for a flexible array member nothing is done -- user must define own assignment
    86         if ( ! array->get_dimension() ) return ;
    87 
    88         Expression * begin, * end, * update, * cmp;
    89         if ( forward ) {
    90             // generate: for ( int i = 0; i < N; ++i )
    91             begin = new ConstantExpr( Constant::from_int( 0 ) );
    92             end = array->get_dimension()->clone();
    93             cmp = new NameExpr( "?<?" );
    94             update = new NameExpr( "++?" );
    95         } else {
    96             // generate: for ( int i = N-1; i >= 0; --i )
    97             begin = new UntypedExpr( new NameExpr( "?-?" ) );
    98             ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    99             ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
    100             end = new ConstantExpr( Constant::from_int( 0 ) );
    101             cmp = new NameExpr( "?>=?" );
    102             update = new NameExpr( "--?" );
    10376        }
    10477
    105         ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
     78        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
     79        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
     80        template< typename OutputIterator >
     81        void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
     82                static UniqueName indexName( "_index" );
    10683
    107         UntypedExpr *cond = new UntypedExpr( cmp );
    108         cond->get_args().push_back( new VariableExpr( index ) );
    109         cond->get_args().push_back( end );
     84                // for a flexible array member nothing is done -- user must define own assignment
     85                if ( ! array->get_dimension() ) return ;
    11086
    111         UntypedExpr *inc = new UntypedExpr( update );
    112         inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     87                Expression * begin, * end, * update, * cmp;
     88                if ( forward ) {
     89                        // generate: for ( int i = 0; i < N; ++i )
     90                        begin = new ConstantExpr( Constant::from_int( 0 ) );
     91                        end = array->get_dimension()->clone();
     92                        cmp = new NameExpr( "?<?" );
     93                        update = new NameExpr( "++?" );
     94                } else {
     95                        // generate: for ( int i = N-1; i >= 0; --i )
     96                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
     97                        ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     98                        ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     99                        end = new ConstantExpr( Constant::from_int( 0 ) );
     100                        cmp = new NameExpr( "?>=?" );
     101                        update = new NameExpr( "--?" );
     102                }
    113103
    114         UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    115         dstIndex->get_args().push_back( dstParam );
    116         dstIndex->get_args().push_back( new VariableExpr( index ) );
    117         dstParam = dstIndex;
     104                ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin ) );
    118105
    119         // srcParam must keep track of the array indices to build the
    120         // source parameter and/or array list initializer
    121         srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
     106                UntypedExpr *cond = new UntypedExpr( cmp );
     107                cond->get_args().push_back( new VariableExpr( index ) );
     108                cond->get_args().push_back( end );
    122109
    123         // for stmt's body, eventually containing call
    124         CompoundStmt * body = new CompoundStmt( noLabels );
    125         Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     110                UntypedExpr *inc = new UntypedExpr( update );
     111                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    126112
    127         // block containing for stmt and index variable
    128         std::list<Statement *> initList;
    129         CompoundStmt * block = new CompoundStmt( noLabels );
    130         block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    131         if ( listInit ) block->get_kids().push_back( listInit );
    132         block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     113                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     114                dstIndex->get_args().push_back( dstParam );
     115                dstIndex->get_args().push_back( new VariableExpr( index ) );
     116                dstParam = dstIndex;
    133117
    134         *out++ = block;
    135     }
     118                // srcParam must keep track of the array indices to build the
     119                // source parameter and/or array list initializer
     120                srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    136121
    137     template< typename OutputIterator >
     122                // for stmt's body, eventually containing call
     123                CompoundStmt * body = new CompoundStmt( noLabels );
     124                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     125
     126                // block containing for stmt and index variable
     127                std::list<Statement *> initList;
     128                CompoundStmt * block = new CompoundStmt( noLabels );
     129                block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     130                if ( listInit ) block->get_kids().push_back( listInit );
     131                block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     132
     133                *out++ = block;
     134        }
     135
     136        template< typename OutputIterator >
    138137        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    139         if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    140             genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
    141             return 0;
    142         } else {
    143             return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     138                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     139                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     140                        return 0;
     141                } else {
     142                        return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     143                }
    144144        }
    145     }
    146145
    147     /// inserts into out a generated call expression to function fname with arguments dstParam
    148     /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
    149     /// object being constructed. The function wraps constructor and destructor calls in an
    150     /// ImplicitCtorDtorStmt node.
    151     template< typename OutputIterator >
     146        /// inserts into out a generated call expression to function fname with arguments dstParam
     147        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     148        /// object being constructed. The function wraps constructor and destructor calls in an
     149        /// ImplicitCtorDtorStmt node.
     150        template< typename OutputIterator >
    152151        void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    153         ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    154         assert( obj );
    155         // unnamed bit fields are not copied as they cannot be accessed
    156         if ( isUnnamedBitfield( obj ) ) return;
     152                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
     153                assert( obj );
     154                // unnamed bit fields are not copied as they cannot be accessed
     155                if ( isUnnamedBitfield( obj ) ) return;
    157156
    158         bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
    159         std::list< Statement * > stmts;
    160         genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
     157                bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
     158                std::list< Statement * > stmts;
     159                genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
    161160
    162         // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
    163         assert( stmts.size() <= 1 );
    164         if ( stmts.size() == 1 ) {
    165             Statement * callStmt = stmts.front();
    166             if ( addCast ) {
    167                 // implicitly generated ctor/dtor calls should be wrapped
    168                 // so that later passes are aware they were generated.
    169                 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    170                 // because this causes the address to be taken at codegen, which is illegal in C.
    171                 callStmt = new ImplicitCtorDtorStmt( callStmt );
    172             }
    173             *out++ = callStmt;
     161                // 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
     162                assert( stmts.size() <= 1 );
     163                if ( stmts.size() == 1 ) {
     164                        Statement * callStmt = stmts.front();
     165                        if ( addCast ) {
     166                                // implicitly generated ctor/dtor calls should be wrapped
     167                                // so that later passes are aware they were generated.
     168                                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     169                                // because this causes the address to be taken at codegen, which is illegal in C.
     170                                callStmt = new ImplicitCtorDtorStmt( callStmt );
     171                        }
     172                        *out++ = callStmt;
     173                }
    174174        }
    175     }
    176175} // namespace SymTab
    177176#endif // AUTOGEN_H
  • src/SymTab/ImplementationType.cc

    r11dbfe1 r67fa9f9  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ImplementationType.cc -- 
     7// ImplementationType.cc --
    88//
    99// Author           : Richard C. Bilson
     
    9292
    9393        void ImplementationType::visit(TupleType *tupleType) {
    94                 TupleType *newType = new TupleType( Type::Qualifiers() );
     94                std::list< Type * > types;
    9595                for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
    9696                        Type *implType = implementationType( *i, indexer );
    9797                        implType->get_qualifiers() |= tupleType->get_qualifiers();
    98                         newType->get_types().push_back( implType );
     98                        types.push_back( implType );
    9999                } // for
    100                 result = newType;
     100                result = new TupleType( Type::Qualifiers(), types );
    101101        }
    102102
  • src/SymTab/Indexer.cc

    r11dbfe1 r67fa9f9  
    652652                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    653653                                // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    654                                 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true;
     654                                if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true;
    655655                        }
    656656                }
     
    669669                                // check for C decls with the same name, skipping
    670670                                // those with an incompatible type (by mangleName)
    671                                 if ( decl->second->get_linkage() == LinkageSpec::C && decl->first == mangleName ) return true;
     671                                if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true;
    672672                        }
    673673                }
     
    724724                        // new definition shadows the autogenerated one, even at the same scope
    725725                        return false;
    726                 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
     726                } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
    727727                        // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
    728728                        // we should ignore outermost pointer qualifiers, except _Atomic?
     
    765765
    766766                // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
    767                 if ( decl->get_linkage() == LinkageSpec::C ) {
     767                if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) {
    768768                        // NOTE this is broken in Richard's original code in such a way that it never triggers (it
    769769                        // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
  • src/SymTab/Validate.cc

    r11dbfe1 r67fa9f9  
    106106
    107107        /// Fix return types so that every function returns exactly one value
    108         class ReturnTypeFixer {
    109           public:
     108        struct ReturnTypeFixer {
    110109                static void fix( std::list< Declaration * > &translationUnit );
    111110
     
    115114
    116115        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    117         class EnumAndPointerDecay {
    118         public:
     116        struct EnumAndPointerDecay {
    119117                void previsit( EnumDecl *aggregateDecl );
    120118                void previsit( FunctionType *func );
     
    159157        };
    160158
    161         class ReturnChecker : public WithScopes {
    162           public:
     159        struct ReturnChecker : public WithGuards {
    163160                /// Checks that return statements return nothing if their return type is void
    164161                /// and return something if the return type is non-void.
    165162                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    166           private:
     163
    167164                void previsit( FunctionDecl * functionDecl );
    168165                void previsit( ReturnStmt * returnStmt );
     
    205202        };
    206203
    207         class VerifyCtorDtorAssign {
    208         public:
     204        struct VerifyCtorDtorAssign {
    209205                /// ensure that constructors, destructors, and assignment have at least one
    210206                /// parameter, the first of which must be a pointer, and that ctor/dtors have no
     
    216212
    217213        /// ensure that generic types have the correct number of type arguments
    218         class ValidateGenericParameters {
    219         public:
     214        struct ValidateGenericParameters {
    220215                void previsit( StructInstType * inst );
    221216                void previsit( UnionInstType * inst );
    222217        };
    223218
    224         class ArrayLength {
    225         public:
     219        struct ArrayLength {
    226220                /// for array types without an explicit length, compute the length and store it so that it
    227221                /// is known to the rest of the phases. For example,
     
    236230        };
    237231
    238         class CompoundLiteral final : public GenPoly::DeclMutator {
     232        struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
    239233                Type::StorageClasses storageClasses;
    240234
    241                 using GenPoly::DeclMutator::mutate;
    242                 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
    243                 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
     235                void premutate( ObjectDecl *objectDecl );
     236                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    244237        };
    245238
     
    248241                LinkReferenceToTypes lrt( doDebug, 0 );
    249242                ForallPointerDecay fpd( 0 );
    250                 CompoundLiteral compoundliteral;
     243                PassVisitor<CompoundLiteral> compoundliteral;
    251244                PassVisitor<ValidateGenericParameters> genericParams;
    252245
     
    263256                Concurrency::implementThreadStarter( translationUnit );
    264257                ReturnChecker::checkFunctionReturns( translationUnit );
    265                 compoundliteral.mutateDeclarationList( translationUnit );
     258                mutateAll( translationUnit, compoundliteral );
    266259                acceptAll( translationUnit, fpd );
    267260                ArrayLength::computeLength( translationUnit );
     
    883876        }
    884877
    885         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
     878        void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
    886879                storageClasses = objectDecl->get_storageClasses();
    887                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    888                 return temp;
    889         }
    890 
    891         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
     880        }
     881
     882        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    892883                // transform [storage_class] ... (struct S){ 3, ... };
    893884                // into [storage_class] struct S temp =  { 3, ... };
    894885                static UniqueName indexName( "_compLit" );
    895886
    896                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );
    897                 compLitExpr->set_result( 0 );
    898                 compLitExpr->set_initializer( 0 );
     887                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     888                compLitExpr->set_result( nullptr );
     889                compLitExpr->set_initializer( nullptr );
    899890                delete compLitExpr;
    900                 DeclarationWithType * newtempvar = mutate( tempvar );
    901                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    902                 return new VariableExpr( newtempvar );
     891                declsToAddBefore.push_back( tempvar );                                  // add modified temporary to current block
     892                return new VariableExpr( tempvar );
    903893        }
    904894
Note: See TracChangeset for help on using the changeset viewer.