Changeset 4d2d7e27 for src


Ignore:
Timestamp:
Oct 16, 2023, 3:04:18 PM (14 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
278e162
Parents:
54e59dd (diff), e14d169 (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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/BoxNew.cpp

    r54e59dd r4d2d7e27  
    376376        ast::Expr const * postvisit( ast::AddressExpr const * expr );
    377377        ast::ReturnStmt const * previsit( ast::ReturnStmt const * stmt );
    378         void previsit( ast::PointerType const * type );
    379         void previsit( ast::FunctionType const * type );
    380378
    381379        void beginScope();
     
    386384        // return value.
    387385
    388         /// Pass the extra type parameters from polymorphic generic arguments or
    389         /// return types into a function application.
    390         ast::vector<ast::Expr>::iterator passArgTypeVars(
    391                 ast::ApplicationExpr * expr, ast::Type const * parmType,
    392                 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
    393                 const TypeVarMap & exprTyVars, std::set<std::string> & seenTypes );
    394         /// Passes extra type parameters into a polymorphic function application.
     386        /// Passes extra layout arguments for sized polymorphic type parameters.
    395387        ast::vector<ast::Expr>::iterator passTypeVars(
    396388                ast::ApplicationExpr * expr,
    397                 ast::Type const * polyRetType,
    398                 ast::FunctionType const * funcType,
    399                 const TypeVarMap & exprTyVars );
     389                ast::FunctionType const * funcType );
    400390        /// Wraps a function application with a new temporary for the
    401391        /// out-parameter return value.
     
    561551
    562552ast::FunctionDecl const * CallAdapter::previsit( ast::FunctionDecl const * decl ) {
     553        // Prevent type declaration information from leaking out.
     554        GuardScope( scopeTypeVars );
     555
    563556        if ( nullptr == decl->stmts ) {
    564                 // This may keep TypeDecls we don't ever want from sneaking in.
    565                 // Not visiting child nodes might just be faster.
    566                 GuardScope( scopeTypeVars );
    567557                return decl;
    568558        }
    569559
    570         GuardScope( scopeTypeVars );
    571560        GuardValue( retval );
    572561
     
    695684
    696685        assert( typeSubs );
    697         ast::Type const * concRetType = replaceWithConcrete( dynRetType, *typeSubs );
    698         // Used to use dynRetType instead of concRetType; this changed so that
    699         // the correct type parameters are passed for return types (it should be
    700         // the concrete type's parameters, not the formal type's).
    701686        ast::vector<ast::Expr>::iterator argIt =
    702                 passTypeVars( mutExpr, concRetType, function, exprTypeVars );
     687                passTypeVars( mutExpr, function );
    703688        addInferredParams( mutExpr, argIt, function, exprTypeVars );
    704689
     
    778763}
    779764
    780 void CallAdapter::previsit( ast::PointerType const * type ) {
    781         GuardScope( scopeTypeVars );
    782         makeTypeVarMap( type, scopeTypeVars );
    783 }
    784 
    785 void CallAdapter::previsit( ast::FunctionType const * type ) {
    786         GuardScope( scopeTypeVars );
    787         makeTypeVarMap( type, scopeTypeVars );
    788 }
    789 
    790765void CallAdapter::beginScope() {
    791766        adapters.beginScope();
     
    812787}
    813788
    814 // arg is an in/out parameter that matches the return value.
    815 ast::vector<ast::Expr>::iterator CallAdapter::passArgTypeVars(
    816                 ast::ApplicationExpr * expr, ast::Type const * paramType,
    817                 ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
    818                 const TypeVarMap & exprTypeVars, std::set<std::string> & seenTypes ) {
    819         ast::Type const * polyType = isPolyType( paramType, exprTypeVars );
    820         if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    821                 return arg;
    822         }
    823 
    824         std::string typeName = Mangle::mangleType( polyType );
    825         if ( seenTypes.count( typeName ) ) return arg;
    826 
    827         arg = expr->args.insert( arg,
    828                 new ast::SizeofExpr( expr->location, ast::deepCopy( argBaseType ) )
    829         );
    830         arg++;
    831         arg = expr->args.insert( arg,
    832                 new ast::AlignofExpr( expr->location, ast::deepCopy( argBaseType ) )
    833         );
    834         arg++;
    835         if ( dynamic_cast<ast::StructInstType const *>( polyType ) ) {
    836                 auto argBaseStructType =
    837                                 dynamic_cast<ast::StructInstType const *>( argBaseType );
    838                 if ( nullptr == argBaseStructType ) {
    839                         SemanticError( expr,
    840                                 "Cannot pass non-structure type for generic struct: " );
    841                 }
    842 
    843                 // Zero-length arrays are forbidden by C, so don't pass
    844                 // offset for empty structure.
    845                 if ( !argBaseStructType->base->members.empty() ) {
    846                         arg = expr->args.insert( arg,
    847                                 new ast::OffsetPackExpr(
    848                                         expr->location,
    849                                         ast::deepCopy( argBaseStructType ) )
    850                         );
    851                         arg++;
    852                 }
    853         }
    854 
    855         seenTypes.insert( typeName );
    856         return arg;
    857 }
    858 
    859789ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars(
    860790                ast::ApplicationExpr * expr,
    861                 ast::Type const * polyRetType,
    862                 ast::FunctionType const * function,
    863                 const TypeVarMap & exprTypeVars ) {
     791                ast::FunctionType const * function ) {
    864792        assert( typeSubs );
    865793        ast::vector<ast::Expr>::iterator arg = expr->args.begin();
     
    880808                        new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) );
    881809                arg++;
    882         }
    883 
    884         // Add size/align for generic types to parameter list.
    885         if ( !expr->func->result ) return arg;
    886         ast::FunctionType const * funcType = getFunctionType( expr->func->result );
    887         assert( funcType );
    888 
    889         // This iterator points at first original argument.
    890         ast::vector<ast::Expr>::const_iterator funcArg;
    891         // Names for generic types we've seen.
    892         std::set<std::string> seenTypes;
    893 
    894         // A polymorphic return type may need to be added to the argument list.
    895         if ( polyRetType ) {
    896                 assert( typeSubs );
    897                 auto concRetType = replaceWithConcrete( polyRetType, *typeSubs );
    898                 // TODO: This write-back may not be correct.
    899                 arg = passArgTypeVars( expr, polyRetType, concRetType,
    900                                 arg, exprTypeVars, seenTypes );
    901                 // Skip the return parameter in the argument list.
    902                 funcArg = arg + 1;
    903         } else {
    904                 funcArg = arg;
    905         }
    906 
    907         // TODO:
    908         // I believe this is (starts as) the number of original arguments to the
    909         // function with the args before funcArg all being inserted.
    910         ptrdiff_t argsToPass = std::distance( funcArg, expr->args.cend() );
    911 
    912         // Add type information args for presently unseen types in parameter list.
    913         ast::vector<ast::Type>::const_iterator funcParam = funcType->params.begin();
    914         // assert( funcType->params.size() == argsToPass );
    915         for ( ; funcParam != funcType->params.end() && 0 < argsToPass
    916                         ; ++funcParam, --argsToPass ) {
    917                 assert( 0 < argsToPass );
    918                 assert( argsToPass <= (ptrdiff_t)expr->args.size() );
    919                 ptrdiff_t index = expr->args.size() - argsToPass;
    920                 ast::Type const * argType = expr->args[index]->result;
    921                 if ( nullptr == argType ) continue;
    922                 arg = passArgTypeVars( expr, *funcParam, argType,
    923                                 arg, exprTypeVars, seenTypes );
    924810        }
    925811        return arg;
     
    15231409}
    15241410
    1525 ast::ObjectDecl * makePtr(
    1526                 CodeLocation const & location, std::string const & name ) {
    1527         return new ast::ObjectDecl( location, name,
    1528                 new ast::PointerType( makeSizeAlignType() ),
    1529                 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );
    1530 }
    1531 
    15321411ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    15331412        TypeVarMap localTypeVars = { ast::TypeData() };
     
    15841463        mutDecl->assertions.clear();
    15851464
    1586         // Add size/align for generic parameter types to parameter list.
    1587         std::set<std::string> seenTypes;
    1588         ast::vector<ast::DeclWithType> otypeParams;
    1589         for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
    1590                 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
    1591                 if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    1592                         continue;
    1593                 }
    1594                 std::string typeName = Mangle::mangleType( polyType );
    1595                 if ( seenTypes.count( typeName ) ) continue;
    1596                 seenTypes.insert( typeName );
    1597 
    1598                 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
    1599                 otypeParams.emplace_back( sizeParam );
    1600 
    1601                 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
    1602                 otypeParams.emplace_back( alignParam );
    1603 
    1604                 // Zero-length arrays are illegal in C, so empty structs have no
    1605                 // offset array.
    1606                 if ( auto * polyStruct =
    1607                                 dynamic_cast<ast::StructInstType const *>( polyType ) ;
    1608                                 polyStruct && !polyStruct->base->members.empty() ) {
    1609                         auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) );
    1610                         otypeParams.emplace_back( offsetParam );
    1611                 }
    1612         }
    1613 
    16141465        // Prepend each argument group. From last group to first. addAdapters
    16151466        // does do the same, it just does it itself and see all other parameters.
    16161467        spliceBegin( mutDecl->params, inferredParams );
    1617         spliceBegin( mutDecl->params, otypeParams );
    16181468        spliceBegin( mutDecl->params, layoutParams );
    16191469        addAdapters( mutDecl, localTypeVars );
     
    17281578        PolyGenericCalculator();
    17291579
    1730         void previsit( ast::ObjectDecl const * decl );
    17311580        void previsit( ast::FunctionDecl const * decl );
    17321581        void previsit( ast::TypedefDecl const * decl );
     
    17351584        ast::StructDecl const * previsit( ast::StructDecl const * decl );
    17361585        ast::UnionDecl const * previsit( ast::UnionDecl const * decl );
    1737         void previsit( ast::PointerType const * type );
    1738         void previsit( ast::FunctionType const * type );
    17391586        ast::DeclStmt const * previsit( ast::DeclStmt const * stmt );
    17401587        ast::Expr const * postvisit( ast::MemberExpr const * expr );
     
    17721619        /// adding the type variables from the provided type.
    17731620        void beginTypeScope( ast::Type const * );
    1774         /// Enters a new scope for known layouts and offsets, and queues exit calls.
    1775         void beginGenericScope();
    17761621
    17771622        /// Set of generic type layouts known in the current scope,
     
    17851630        /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    17861631        ast::MemberExpr const * addrMember = nullptr;
    1787         /// Used to avoid recursing too deep in type declarations.
    1788         bool expect_func_type = false;
    17891632};
    17901633
     
    18081651}
    18091652
    1810 void PolyGenericCalculator::previsit( ast::ObjectDecl const * decl ) {
     1653void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {
     1654        GuardScope( *this );
    18111655        beginTypeScope( decl->type );
    1812 }
    1813 
    1814 void PolyGenericCalculator::previsit( ast::FunctionDecl const * decl ) {
    1815         beginGenericScope();
    1816         beginTypeScope( decl->type );
    1817 
    1818         // TODO: Going though dec->params does not work for some reason.
    1819         for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
    1820                 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
    1821                 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
    1822                 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    1823                         knownLayouts.insert( Mangle::mangleType( polyType ) );
    1824                 }
    1825         }
    18261656}
    18271657
     
    18841714}
    18851715
    1886 void PolyGenericCalculator::previsit( ast::PointerType const * type ) {
    1887         beginTypeScope( type );
    1888 }
    1889 
    1890 void PolyGenericCalculator::previsit( ast::FunctionType const * type ) {
    1891         beginTypeScope( type );
    1892 
    1893         GuardValue( expect_func_type );
    1894         GuardScope( *this );
    1895 
    1896         // The other functions type we will see in this scope are probably
    1897         // function parameters they don't help us with the layout and offsets so
    1898         // don't mark them as known in this scope.
    1899         expect_func_type = false;
    1900 
    1901         // Make sure that any type information passed into the function is
    1902         // accounted for.
    1903         for ( ast::ptr<ast::Type> const & funcParam : type->params ) {
    1904                 // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
    1905                 ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
    1906                 if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    1907                         knownLayouts.insert( Mangle::mangleType( polyType ) );
    1908                 }
    1909         }
    1910 }
    1911 
    1912 //void PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    19131716ast::DeclStmt const * PolyGenericCalculator::previsit( ast::DeclStmt const * stmt ) {
    19141717        ast::ObjectDecl const * decl = stmt->decl.as<ast::ObjectDecl>();
     
    24002203}
    24012204
    2402 void PolyGenericCalculator::beginGenericScope() {
    2403         GuardScope( *this );
    2404         // We expect the first function type see to be the type relating to this
    2405         // scope but any further type is probably some unrelated function pointer
    2406         // keep track of whrich is the first.
    2407         GuardValue( expect_func_type ) = true;
    2408 }
    2409 
    24102205// --------------------------------------------------------------------------
    2411 /// No common theme found.
     2206/// Removes unneeded or incorrect type information.
    24122207/// * Replaces initialization of polymorphic values with alloca.
    24132208/// * Replaces declaration of dtype/ftype with appropriate void expression.
Note: See TracChangeset for help on using the changeset viewer.