Changeset fb4dc28 for src/SymTab


Ignore:
Timestamp:
Apr 14, 2023, 3:55:06 PM (13 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master
Children:
d859a30
Parents:
1b8fc06c
Message:

Moved new ast code out of one of the old files. The new file may have to change if SymTab? is removed entirely, but for now at least, there is a lot less template code in headers.

Location:
src/SymTab
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r1b8fc06c rfb4dc28  
    1010// Created On       : Thu Mar 03 15:45:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr 27 14:39:06 2018
    13 // Update Count     : 63
     12// Last Modified On : Fri Apr 14 15:03:00 2023
     13// Update Count     : 64
    1414//
    1515
     
    211211        }
    212212
    213         bool isUnnamedBitfield( const ast::ObjectDecl * obj ) {
    214                 return obj && obj->name.empty() && obj->bitfieldWidth;
    215         }
    216 
    217213        /// inserts a forward declaration for functionDecl into declsToAdd
    218214        void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
     
    234230        }
    235231
    236         // shallow copy the pointer list for return
    237         std::vector<ast::ptr<ast::TypeDecl>> getGenericParams (const ast::Type * t) {
    238                 if (auto structInst = dynamic_cast<const ast::StructInstType*>(t)) {
    239                         return structInst->base->params;
    240                 }
    241                 if (auto unionInst = dynamic_cast<const ast::UnionInstType*>(t)) {
    242                         return unionInst->base->params;
    243                 }
    244                 return {};
    245         }
    246 
    247232        /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *)
    248233        FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic ) {
     
    256241                ftype->parameters.push_back( dstParam );
    257242                return ftype;
    258         }
    259 
    260         /// Given type T, generate type of default ctor/dtor, i.e. function type void (*) (T &).
    261         ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic) {
    262                 std::vector<ast::ptr<ast::TypeDecl>> typeParams;
    263                 if (maybePolymorphic) typeParams = getGenericParams(paramType);
    264                 auto dstParam = new ast::ObjectDecl(loc, "_dst", new ast::ReferenceType(paramType), nullptr, {}, ast::Linkage::Cforall);
    265                 return new ast::FunctionDecl(loc, fname, std::move(typeParams), {dstParam}, {}, new ast::CompoundStmt(loc), {}, ast::Linkage::Cforall);
    266243        }
    267244
  • src/SymTab/Autogen.h

    r1b8fc06c rfb4dc28  
    99// Author           : Rob Schluntz
    1010// Created On       : Sun May 17 21:53:34 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 16:38:06 2019
    13 // Update Count     : 16
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Apr 14 15:06:00 2023
     13// Update Count     : 17
    1414//
    1515
     
    4545        /// returns true if obj's name is the empty string and it has a bitfield width
    4646        bool isUnnamedBitfield( ObjectDecl * obj );
    47         bool isUnnamedBitfield( const ast::ObjectDecl * obj );
    4847
    4948        /// generate the type of an assignment function for paramType.
     
    5554        FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true );
    5655
    57         ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic = true);
    58 
    5956        /// generate the type of a copy constructor for paramType.
    6057        /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
     
    6764        template< typename OutputIterator >
    6865        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
    69 
    70         template< typename OutIter >
    71         ast::ptr< ast::Stmt > genCall(
    72                 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
    73                 const CodeLocation & loc, const std::string & fname, OutIter && out,
    74                 const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward );
    7566
    7667        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
     
    121112
    122113                *out++ = new ExprStmt( fExpr );
    123 
    124                 srcParam.clearArrayIndices();
    125 
    126                 return listInit;
    127         }
    128 
    129         /// inserts into out a generated call expression to function fname with arguments dstParam and
    130         /// srcParam. Should only be called with non-array types.
    131         /// optionally returns a statement which must be inserted prior to the containing loop, if
    132         /// there is one
    133         template< typename OutIter >
    134         ast::ptr< ast::Stmt > genScalarCall(
    135                 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
    136                 const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type,
    137                 const ast::Type * addCast = nullptr
    138         ) {
    139                 bool isReferenceCtorDtor = false;
    140                 if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
    141                         // reference constructors are essentially application of the rebind operator.
    142                         // apply & to both arguments, do not need a cast
    143                         fname = "?=?";
    144                         dstParam = new ast::AddressExpr{ dstParam };
    145                         addCast = nullptr;
    146                         isReferenceCtorDtor = true;
    147                 }
    148 
    149                 // want to be able to generate assignment, ctor, and dtor generically, so fname is one of
    150                 // "?=?", "?{}", or "^?{}"
    151                 ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } };
    152 
    153                 if ( addCast ) {
    154                         // cast to T& with qualifiers removed, so that qualified objects can be constructed and
    155                         // destructed with the same functions as non-qualified objects. Unfortunately, lvalue
    156                         // is considered a qualifier - for AddressExpr to resolve, its argument must have an
    157                         // lvalue-qualified type, so remove all qualifiers except lvalue.
    158                         // xxx -- old code actually removed lvalue too...
    159                         ast::ptr< ast::Type > guard = addCast;  // prevent castType from mutating addCast
    160                         ast::ptr< ast::Type > castType = addCast;
    161                         ast::remove_qualifiers(
    162                                 castType,
    163                                 ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic );
    164                         dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } };
    165                 }
    166                 fExpr->args.emplace_back( dstParam );
    167 
    168                 ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr );
    169 
    170                 // fetch next set of arguments
    171                 ++srcParam;
    172 
    173                 // return if adding reference fails -- will happen on default ctor and dtor
    174                 if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit;
    175 
    176                 std::vector< ast::ptr< ast::Expr > > args = *srcParam;
    177                 splice( fExpr->args, args );
    178 
    179                 *out++ = new ast::ExprStmt{ loc, fExpr };
    180114
    181115                srcParam.clearArrayIndices();
     
    248182        }
    249183
    250         /// Store in out a loop which calls fname on each element of the array with srcParam and
    251         /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0
    252         template< typename OutIter >
    253         void genArrayCall(
    254                 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
    255                 const CodeLocation & loc, const std::string & fname, OutIter && out,
    256                 const ast::ArrayType * array, const ast::Type * addCast = nullptr,
    257                 LoopDirection forward = LoopForward
    258         ) {
    259                 static UniqueName indexName( "_index" );
    260 
    261                 // for a flexible array member nothing is done -- user must define own assignment
    262                 if ( ! array->dimension ) return;
    263 
    264                 if ( addCast ) {
    265                         // peel off array layer from cast
    266                         addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base;
    267                 }
    268 
    269                 ast::ptr< ast::Expr > begin, end;
    270                 std::string cmp, update;
    271 
    272                 if ( forward ) {
    273                         // generate: for ( int i = 0; i < N; ++i )
    274                         begin = ast::ConstantExpr::from_int( loc, 0 );
    275                         end = array->dimension;
    276                         cmp = "?<?";
    277                         update = "++?";
    278                 } else {
    279                         // generate: for ( int i = N-1; i >= 0; --i )
    280                         begin = ast::UntypedExpr::createCall( loc, "?-?",
    281                                 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } );
    282                         end = ast::ConstantExpr::from_int( loc, 0 );
    283                         cmp = "?>=?";
    284                         update = "--?";
    285                 }
    286 
    287                 ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{
    288                         loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt },
    289                         new ast::SingleInit{ loc, begin } };
    290                 ast::ptr< ast::Expr > indexVar = new ast::VariableExpr{ loc, index };
    291 
    292                 ast::ptr< ast::Expr > cond = ast::UntypedExpr::createCall(
    293                         loc, cmp, { indexVar, end } );
    294 
    295                 ast::ptr< ast::Expr > inc = ast::UntypedExpr::createCall(
    296                         loc, update, { indexVar } );
    297 
    298                 ast::ptr< ast::Expr > dstIndex = ast::UntypedExpr::createCall(
    299                         loc, "?[?]", { dstParam, indexVar } );
    300 
    301                 // srcParam must keep track of the array indices to build the source parameter and/or
    302                 // array list initializer
    303                 srcParam.addArrayIndex( indexVar, array->dimension );
    304 
    305                 // for stmt's body, eventually containing call
    306                 ast::CompoundStmt * body = new ast::CompoundStmt{ loc };
    307                 ast::ptr< ast::Stmt > listInit = genCall(
    308                         srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast,
    309                         forward );
    310 
    311                 // block containing the stmt and index variable
    312                 ast::CompoundStmt * block = new ast::CompoundStmt{ loc };
    313                 block->push_back( new ast::DeclStmt{ loc, index } );
    314                 if ( listInit ) { block->push_back( listInit ); }
    315                 block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } );
    316 
    317                 *out++ = block;
    318         }
    319 
    320184        template< typename OutputIterator >
    321185        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
     
    325189                } else {
    326190                        return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
    327                 }
    328         }
    329 
    330         template< typename OutIter >
    331         ast::ptr< ast::Stmt > genCall(
    332                 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
    333                 const CodeLocation & loc, const std::string & fname, OutIter && out,
    334                 const ast::Type * type, const ast::Type * addCast, LoopDirection forward
    335         ) {
    336                 if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
    337                         genArrayCall(
    338                                 srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast,
    339                                 forward );
    340                         return {};
    341                 } else {
    342                         return genScalarCall(
    343                                 srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast );
    344191                }
    345192        }
     
    379226        }
    380227
    381         static inline ast::ptr< ast::Stmt > genImplicitCall(
    382                 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
    383                 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj,
    384                 LoopDirection forward = LoopForward
    385         ) {
    386                 // unnamed bit fields are not copied as they cannot be accessed
    387                 if ( isUnnamedBitfield( obj ) ) return {};
    388 
    389                 ast::ptr< ast::Type > addCast;
    390                 if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) {
    391                         assert( dstParam->result );
    392                         addCast = dstParam->result;
    393                 }
    394 
    395                 std::vector< ast::ptr< ast::Stmt > > stmts;
    396                 genCall(
    397                         srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward );
    398 
    399                 if ( stmts.empty() ) {
    400                         return {};
    401                 } else if ( stmts.size() == 1 ) {
    402                         const ast::Stmt * callStmt = stmts.front();
    403                         if ( addCast ) {
    404                                 // implicitly generated ctor/dtor calls should be wrapped so that later passes are
    405                                 // aware they were generated.
    406                                 callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt };
    407                         }
    408                         return callStmt;
    409                 } else {
    410                         assert( false );
    411                         return {};
    412                 }
    413         }
    414228} // namespace SymTab
    415229
  • src/SymTab/module.mk

    r1b8fc06c rfb4dc28  
    2020        SymTab/FixFunction.cc \
    2121        SymTab/FixFunction.h \
     22        SymTab/GenImplicitCall.cpp \
     23        SymTab/GenImplicitCall.hpp \
    2224        SymTab/Indexer.cc \
    2325        SymTab/Indexer.h \
Note: See TracChangeset for help on using the changeset viewer.