Changes in / [f45772e:2261bcc]


Ignore:
Files:
2 deleted
23 edited

Legend:

Unmodified
Added
Removed
  • Jenkins/FullBuild

    rf45772e r2261bcc  
    2525                                        gcc_08_x64_new: { trigger_build( 'gcc-8',   'x64', false ) },
    2626                                        gcc_07_x64_new: { trigger_build( 'gcc-7',   'x64', false ) },
    27                                         gcc_11_arm64_new: { trigger_build( 'gcc-11',  'arm64', false ) },
    28                                         gcc_10_arm64_new: { trigger_build( 'gcc-10',  'arm64', false ) },
    29                                         gcc_09_arm64_new: { trigger_build( 'gcc-9',   'arm64', false ) },
    30                                         // gcc_06_arm64_new: { trigger_build( 'gcc-6',   'arm64', false ) },
     27                                        // gcc_06_x64_new: { trigger_build( 'gcc-6',   'x64', false ) },
    3128                                        clang_x64_new:  { trigger_build( 'clang',   'x64', true  ) },
    3229                                )
  • Jenkins/TestRegen

    rf45772e r2261bcc  
    2424                stage('Building x64') {
    2525                        regen_tests('x86_64')
    26                 }
    27 
    28                 stage('Building arm64') {
    29                         regen_tests('arm64')
    3026                }
    3127
  • libcfa/src/collections/string_res.cfa

    rf45772e r2261bcc  
    218218    // Read in chunks.  Often, one chunk is enough.  Keep the string that accumulates chunks last in the heap,
    219219    // so available room is rest of heap.  When a chunk fills the heap, force growth then take the next chunk.
    220     for (bool cont = true; cont; ) {
    221         cont = false;
    222 
     220    for (;;) {
    223221        // Append dummy content to temp, forcing expansion when applicable (occurs always on subsequent loops)
    224222        // length 2 ensures room for at least one real char, plus scanf/pipe-cstr's null terminator
     
    230228        temp.Handle.ulink->EndVbyte -= 2;
    231229
    232         // rest of heap is available to read into
    233         int lenReadable = (char*)temp.Handle.ulink->ExtVbyte - temp.Handle.ulink->EndVbyte;
    234         assert (lenReadable >= 2);
     230        // rest of heap, less 1 byte for null terminator, is available to read into
     231        int lenReadable = (char*)temp.Handle.ulink->ExtVbyte - temp.Handle.ulink->EndVbyte - 1;
     232        assert (lenReadable >= 1);
    235233
    236234        // get bytes
    237         try {
    238             in | wdi( lenReadable, temp.Handle.ulink->EndVbyte );
    239         } catch (cstring_length*) {
    240             cont = true;
    241         }
     235        in | wdi( lenReadable + 1, lenReadable, temp.Handle.ulink->EndVbyte );
    242236        int lenWasRead = strlen(temp.Handle.ulink->EndVbyte);
    243237
     
    245239        temp.Handle.lnth += lenWasRead;
    246240        temp.Handle.ulink->EndVbyte += lenWasRead;
     241
     242      if (lenWasRead < lenReadable) break;
    247243    }
    248244
  • libcfa/src/iostream.cfa

    rf45772e r2261bcc  
    2222#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
    2323#include <complex.h>                                                                    // creal, cimag
    24 #include <ctype.h>                                                                              // isspace
    2524//#include <stdio.h>
    2625
     
    3029extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    3130extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    32 extern char *strchr(const char *str, int ch);
    3331} // extern "C"
    3432
     
    962960        istype & ?|?( istype & is, _Istream_Cskip f ) {
    963961                // printf( "skip %s %d\n", f.scanset, f.wd );
    964                 if ( f.scanset ) {
    965                         int nscanset = strlen(f.scanset);
    966                         char fmtstr[ sizeof("%*[]") + nscanset ];
    967                         int pos = 0;
    968                         fmtstr[pos] = '%';                  pos += 1;
    969                         fmtstr[pos] = '*';                  pos += 1;
    970                         fmtstr[pos] = '[';                  pos += 1;
    971                         strcpy( &fmtstr[pos], f.scanset );  pos += nscanset;
    972                         fmtstr[pos] = ']';                  pos += 1;
    973                         fmtstr[pos] = '\0';
    974                         fmt( is, fmtstr, (void*)0 );  // last arg is dummy: suppress gcc warning
    975                 }
     962                if ( f.scanset ) fmt( is, f.scanset, "" );              // no input arguments
    976963                else for ( f.wd ) fmt( is, "%*c" );
    977964                return is;
     
    993980                        // wd is buffer bytes available (for input chars + null terminator)
    994981                        // rwd is count of input chars
    995                         int rwd;
    996                         if (f.flags.rwd) {
    997                                 verify (f.wd >= 0);
    998                                 rwd = f.wd;
    999                         } else {
    1000                                 verify (f.wd >= 1);
    1001                                 rwd = f.wd - 1;
    1002                         } // if
     982                        int rwd = f.flags.rwd ? f.wd : (f.wd - 1);
    1003983                        start += sprintf( &fmtstr[start], "%d", rwd );
    1004984                }
     
    10201000
    10211001                int check = f.wd - 2;
    1022                 if (! f.flags.ignore ) {
    1023                         f.s[0] = '\0';
    1024                         if ( ! f.flags.rwd ) f.s[check] = '\0';         // insert sentinel
    1025                 }
     1002                if ( ! f.flags.rwd ) f.s[check] = '\0';                 // insert sentinel
    10261003                len = fmt( is, fmtstr, f.s );
    10271004                //fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, f.s[check], f.s );
    10281005
    1029                 if ( ! f.flags.ignore && ! f.flags.rwd && f.s[check] != '\0' ) { // sentinel overwritten ?
    1030                         // buffer filled, but would we have kept going?
    1031                         if ( ! eof( is ) ) {
    1032                                 char peek;
    1033                                 fmt( is, "%c", &peek );
    1034                                 ungetc( is, peek );
    1035                                 bool hasMore;
    1036                                 if (f.flags.delimiter) { // getline
    1037                                         hasMore = (peek != f.delimiter[0]);
    1038                                 } else if (f.scanset) { // incl/excl
    1039                                         bool peekMatch = strchr(f.scanset, peek) != 0p;
    1040                                         hasMore = f.flags.inex ? (!peekMatch) : (peekMatch);
    1041                                 } else { // %s
    1042                                         hasMore = !isspace(peek);
    1043                                 }
    1044                                 if (hasMore) throw (cstring_length){ &cstring_length_vt };
    1045                         } // if
    1046                 } // if
     1006                if ( ! f.flags.rwd && f.s[check] != '\0' )              // sentinel overwritten ?
     1007                        throw (cstring_length){ &cstring_length_vt };
    10471008
    10481009                if ( f.flags.delimiter ) {                                              // getline ?
  • src/CodeGen/LinkOnce.cc

    rf45772e r2261bcc  
    1010// Created On       : Thur May 13 10:10:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Oct  4 10:52:00 2023
    13 // Update Count     : 1
     12// Last Modified On : Thur May 13 14:39:00 2021
     13// Update Count     : 0
    1414//
    1515
     
    1818#include <algorithm>
    1919
    20 #include "AST/Attribute.hpp"
    21 #include "AST/Decl.hpp"
    22 #include "AST/Expr.hpp"
    23 #include "AST/Pass.hpp"
    2420#include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
    2521
    2622namespace CodeGen {
    2723
    28 namespace {
    29 
    30 bool is_cfa_linkonce_old( Attribute const * attr ) {
     24static bool is_cfa_linkonce( Attribute const * attr ) {
    3125        return std::string("cfa_linkonce") == attr->name;
    3226}
    3327
    34 bool is_section_attribute_old( Attribute const * attr ) {
     28static bool is_section_attribute( Attribute const * attr ) {
    3529        return std::string("section") == attr->name;
    3630}
     
    4539                std::list< Attribute * > & attributes = decl->attributes;
    4640                // See if we can find the element:
    47                 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old );
     41                auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce );
    4842                if ( attributes.end() != found ) {
    4943                        // Remove any other sections:
    50                         attributes.remove_if( is_section_attribute_old );
     44                        attributes.remove_if( is_section_attribute );
    5145                        // Iterator to the cfa_linkonce attribute should still be valid.
    5246                        Attribute * attribute = *found;
     
    6963};
    7064
    71 bool is_cfa_linkonce( ast::Attribute const * attr ) {
    72         return "cfa_linkonce" == attr->name;
    73 }
    74 
    75 bool is_section_attribute( ast::Attribute const * attr ) {
    76         return "section" == attr->name;
    77 }
    78 
    79 struct LinkOnceCore : public ast::WithShortCircuiting {
    80         void previsit( ast::Decl const * ) {
    81                 visit_children = false;
    82         }
    83 
    84         ast::DeclWithType const * postvisit( ast::DeclWithType const * decl ) {
    85                 // Check to see if we have to mutate, because should be uncommon.
    86                 {
    87                         auto & attributes = decl->attributes;
    88                         auto found = std::find_if( attributes.begin(), attributes.end(),
    89                                         is_cfa_linkonce );
    90                         if ( attributes.end() == found ) return decl;
    91                 }
    92                 auto mutDecl = mutate( decl );
    93                 auto & attributes = mutDecl->attributes;
    94 
    95                 // Remove all conflicting section attributes.
    96                 erase_if( attributes, is_section_attribute );
    97 
    98                 // Get the attribute, and overwrite it as a section attribute.
    99                 auto found = std::find_if( attributes.begin(), attributes.end(),
    100                                 is_cfa_linkonce );
    101                 assert( attributes.end() != found );
    102                 ast::Attribute * attribute = found->get_and_mutate();
    103                 assert( attribute->params.empty() );
    104                 assert( !decl->mangleName.empty() );
    105 
    106                 attribute->name = "section";
    107                 attribute->params.push_back(
    108                         ast::ConstantExpr::from_string( mutDecl->location,
    109                                 ".gnu.linkonce." + decl->mangleName
    110                         )
    111                 );
    112 
    113                 // Unconditionnaly add "visibility(default)" to anything with
    114                 // .gnu.linkonce visibility is a mess otherwise.
    115                 attributes.push_back( new ast::Attribute( "visibility", {
    116                         ast::ConstantExpr::from_string( mutDecl->location, "default" )
    117                 } ) );
    118                 return mutDecl;
    119         }
    120 };
    121 
    122 } // namespace
    123 
    12465void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
    12566        PassVisitor<LinkOnceVisitorCore> translator;
     
    12768}
    12869
    129 void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
    130         ast::Pass<LinkOnceCore>::run( translationUnit );
    13170}
    132 
    133 } // namespace CodeGen
  • src/CodeGen/LinkOnce.h

    rf45772e r2261bcc  
    1010// Created On       : Thur May 13 10:06:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Oct  4 10:52:00 2023
    13 // Update Count     : 1
     12// Last Modified On : Thur May 13 14:38:00 2021
     13// Update Count     : 0
    1414//
    1515
     
    2323
    2424class Declaration;
    25 namespace ast {
    26         class TranslationUnit;
    27 }
    2825
    2926namespace CodeGen {
    3027
    3128void translateLinkOnce( std::list< Declaration *> & translationUnit );
    32 void translateLinkOnce( ast::TranslationUnit & translationUnit );
    3329/* Convert the cfa_linkonce attribute on top level declaration into
    3430 * a special section declaration (.gnu.linkonce) so that it may be defined
  • src/GenPoly/BoxNew.cpp

    rf45772e r2261bcc  
    7777};
    7878
     79// Formally takeOtypeOnly
    7980/// Get all sized type declarations; those that affect a layout function.
    8081ast::vector<ast::TypeDecl> takeSizedParams(
     
    509510                ast::FunctionType const * function,
    510511                TypeVarMap const & typeVars ) {
     512        // TODO
     513        // NOTE: This function previously used isPolyObj, which failed to produce
     514        // the correct thing in some situations. It's not clear to [Rob Schluntz]
     515        // why this wasn't working.
     516
    511517        // If the return type or a parameter type involved polymorphic types,
    512518        // then the adapter will need to take those polymorphic types as pointers.
     
    581587        ast::FunctionType const * type = decl->type;
    582588        if ( isDynRet( type ) && decl->linkage != ast::Linkage::C ) {
     589                //retval = type->returns.front();
    583590                retval = decl->returns.front();
    584591
     
    741748ast::Expr const * CallAdapter::postvisit( ast::UntypedExpr const * expr ) {
    742749        if ( isPolyDeref( expr, scopeTypeVars, typeSubs ) ) {
     750                // TODO Pretty sure this is just a memory management change.
     751                // Also, I don't understand what this is doing.
     752                //ast::Expr const * ret = expr->args.front();
     753                //expr->args.clear();
     754                //return ret;
    743755                return expr->args.front();
    744756        }
     
    10511063                ast::ptr<ast::Type> newType = ast::deepCopy( param );
    10521064                if ( typeSubs ) typeSubs->apply( newType );
     1065                // TODO: Is this right? (Why wouldn't it be?)
     1066                // I think this is to make sure we can write to the temporary.
     1067                //newType.get_and_mutate()->qt = ast::CV::Qualifiers();
     1068                //reset_qualifiers( newType );
    10531069                ast::ObjectDecl * newObj = makeTemporary( location, newType );
    10541070                auto assign = ast::UntypedExpr::createCall( location, "?=?", {
     
    12291245                        }
    12301246                        return new ast::ObjectDecl( location, pNamer.newName(), param );
    1231                 } ),
     1247                } ), // params
    12321248                map_range<ast::vector<ast::DeclWithType>>( adapterType->returns,
    12331249                                [&rNamer, &location]( ast::ptr<ast::Type> const & retval ) {
    12341250                        return new ast::ObjectDecl( location, rNamer.newName(), retval );
    1235                 } ),
     1251                } ), // returns
    12361252                nullptr, // stmts
    1237                 {}, // storage
    1238                 ast::Linkage::C
     1253                ast::Storage::Classes(), // storage
     1254                ast::Linkage::C // linkage
     1255                // attrs
     1256                // fs
     1257                // isVarArgs
    12391258        );
    12401259
     
    12951314        // Returns a polymorphic type.
    12961315        } else if ( isDynType( adaptee->returns.front(), typeVars ) ) {
     1316                if ( "" == (*paramDecl)->name ) {
     1317                        // TODO: Is it easier to make sure it has a name in the first
     1318                        // place? - I believe this is done, however, I could remove the
     1319                        // condition and just rename for clarity.
     1320                        assertf( false, "Wasn't expecting to get here." );
     1321                        auto mutParam = paramDecl->get_and_mutate();
     1322                        mutParam->name = "_ret";
     1323                        mutParam->linkage = ast::Linkage::C;
     1324                }
    12971325                ast::UntypedExpr * assign = new ast::UntypedExpr( location,
    12981326                        new ast::NameExpr( location, "?=?" ) );
     
    15181546
    15191547// --------------------------------------------------------------------------
    1520 /// Modifies declarations to accept implicit parameters.
     1548/// Creates the adapter functions. TODO
    15211549/// * Move polymorphic returns in function types to pointer-type parameters.
    15221550/// * Adds type size and assertion parameters to parameter lists.
    1523 struct DeclAdapter final {
     1551struct DeclAdapter final :
     1552                public BoxPass,
     1553                public ast::WithGuards {
     1554        void handleAggrDecl();
     1555
     1556        void previsit( ast::StructDecl const * decl );
     1557        void previsit( ast::UnionDecl const * decl );
     1558        void previsit( ast::TraitDecl const * decl );
     1559        void previsit( ast::TypeDecl const * decl );
     1560        void previsit( ast::PointerType const * type );
     1561        void previsit( ast::FunctionType const * type );
    15241562        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
    1525         ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl );
     1563        ast::DeclWithType const * postvisit( ast::FunctionDecl const * decl );
     1564        void previsit( ast::CompoundStmt const * stmt );
    15261565private:
    1527         void addAdapters( ast::FunctionDecl * decl, TypeVarMap & localTypeVars );
     1566        ast::FunctionDecl * addAdapters( ast::FunctionDecl * decl );
     1567
     1568        std::map<UniqueId, std::string> adapterName;
    15281569};
    15291570
    1530 // size/align/offset parameters may not be used, so add the unused attribute.
    1531 ast::ObjectDecl * makeObj(
    1532                 CodeLocation const & location, std::string const & name ) {
    1533         return new ast::ObjectDecl( location, name,
    1534                 makeSizeAlignType(),
    1535                 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr,
    1536                 { new ast::Attribute( "unused" ) } );
    1537 }
    1538 
    1539 ast::ObjectDecl * makePtr(
    1540                 CodeLocation const & location, std::string const & name ) {
    1541         return new ast::ObjectDecl( location, name,
    1542                 new ast::PointerType( makeSizeAlignType() ),
    1543                 nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );
     1571// at must point within [dst.begin(), dst.end()].
     1572template< typename T >
     1573void spliceAt( std::vector< T > & dst, typename std::vector< T >::iterator at,
     1574                std::vector< T > & src ) {
     1575        std::vector< T > tmp;
     1576        tmp.reserve( dst.size() + src.size() );
     1577        typename std::vector< T >::iterator it = dst.begin();
     1578        while ( it != at ) {
     1579                assert( it != dst.end() );
     1580                tmp.emplace_back( std::move( *it ) );
     1581                ++it;
     1582        }
     1583        for ( T & x : src ) { tmp.emplace_back( std::move( x ) ); }
     1584        while ( it != dst.end() ) {
     1585                tmp.emplace_back( std::move( *it ) );
     1586                ++it;
     1587        }
     1588
     1589        dst.clear();
     1590        src.clear();
     1591        tmp.swap( dst );
     1592}
     1593
     1594void DeclAdapter::previsit( ast::StructDecl const * ) {
     1595        // Prevent type vars from leaking into the containing scope.
     1596        GuardScope( scopeTypeVars );
     1597}
     1598
     1599void DeclAdapter::previsit( ast::UnionDecl const * ) {
     1600        // Prevent type vars from leaking into the containing scope.
     1601        GuardScope( scopeTypeVars );
     1602}
     1603
     1604void DeclAdapter::previsit( ast::TraitDecl const * ) {
     1605        // Prevent type vars from leaking into the containing scope.
     1606        GuardScope( scopeTypeVars );
     1607}
     1608
     1609void DeclAdapter::previsit( ast::TypeDecl const * decl ) {
     1610        addToTypeVarMap( decl, scopeTypeVars );
     1611}
     1612
     1613void DeclAdapter::previsit( ast::PointerType const * type ) {
     1614        GuardScope( scopeTypeVars );
     1615        makeTypeVarMap( type, scopeTypeVars );
     1616}
     1617
     1618// TODO: I think this code is redundent.
     1619void DeclAdapter::previsit( ast::FunctionType const * type ) {
     1620        GuardScope( scopeTypeVars );
     1621        makeTypeVarMap( type, scopeTypeVars );
    15441622}
    15451623
    15461624ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1547         TypeVarMap localTypeVars = { ast::TypeData() };
    1548         makeTypeVarMap( decl, localTypeVars );
     1625        GuardScope( scopeTypeVars );
     1626        makeTypeVarMap( decl, scopeTypeVars );
    15491627
    15501628        auto mutDecl = mutate( decl );
     
    15611639
    15621640        // Add size/align and assertions for type parameters to parameter list.
    1563         ast::vector<ast::DeclWithType> inferredParams;
    1564         ast::vector<ast::DeclWithType> layoutParams;
     1641        std::vector<ast::ptr<ast::DeclWithType>>::iterator last = mutDecl->params.begin();
     1642        std::vector<ast::ptr<ast::DeclWithType>> inferredParams;
     1643        // size/align/offset parameters may not be used in body, pass along with unused attribute.
     1644        // TODO: These should be created with proper location and name.
     1645        // TODO: makeSizeAlign[Out]Type are the same as these types, but they may
     1646        // be logically different.
     1647        ast::ObjectDecl newObj( mutDecl->location, "",
     1648                new ast::BasicType( ast::BasicType::LongUnsignedInt ),
     1649                nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr,
     1650                { new ast::Attribute( "unused" ) } );
     1651        ast::ObjectDecl newPtr( mutDecl->location, "",
     1652                new ast::PointerType( new ast::BasicType( ast::BasicType::LongUnsignedInt ) ),
     1653                nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );
    15651654        for ( ast::ptr<ast::TypeDecl> & typeParam : mutDecl->type_params ) {
    15661655                auto mutParam = mutate( typeParam.get() );
    15671656                // Add all size and alignment parameters to parameter list.
    15681657                if ( mutParam->isComplete() ) {
     1658                        //ast::TypeInstType paramType( typeParam->name, typeParam );
    15691659                        ast::TypeInstType paramType( mutParam );
    15701660                        std::string paramName = Mangle::mangleType( &paramType );
    15711661
    1572                         auto sizeParam = makeObj( typeParam->location, sizeofName( paramName ) );
    1573                         layoutParams.emplace_back( sizeParam );
    1574 
    1575                         auto alignParam = makeObj( typeParam->location, alignofName( paramName ) );
    1576                         layoutParams.emplace_back( alignParam );
     1662                        ast::ObjectDecl * sizeParam = ast::deepCopy( &newObj );
     1663                        sizeParam->location = typeParam->location;
     1664                        sizeParam->name = sizeofName( paramName );
     1665                        last = mutDecl->params.insert( last, sizeParam );
     1666                        ++last;
     1667
     1668                        ast::ObjectDecl * alignParam = ast::deepCopy( &newObj );
     1669                        alignParam->location = typeParam->location;
     1670                        alignParam->name = alignofName( paramName );
     1671                        last = mutDecl->params.insert( last, alignParam );
     1672                        ++last;
    15771673                }
    15781674                // TODO: These should possibly all be gone.
     
    16001696        // Add size/align for generic parameter types to parameter list.
    16011697        std::set<std::string> seenTypes;
    1602         ast::vector<ast::DeclWithType> otypeParams;
     1698        std::vector<ast::ptr<ast::DeclWithType>> otypeParams;
    16031699        for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
    1604                 ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
     1700                ast::Type const * polyType = isPolyType( funcParam->get_type(), scopeTypeVars );
    16051701                if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    16061702                        continue;
     
    16081704                std::string typeName = Mangle::mangleType( polyType );
    16091705                if ( seenTypes.count( typeName ) ) continue;
     1706
     1707                ast::ObjectDecl * sizeParam = ast::deepCopy( &newObj );
     1708                sizeParam->location = funcParam->location;
     1709                sizeParam->name = sizeofName( typeName );
     1710                otypeParams.emplace_back( sizeParam );
     1711
     1712                ast::ObjectDecl * alignParam = ast::deepCopy( &newObj );
     1713                alignParam->location = funcParam->location;
     1714                alignParam->name = alignofName( typeName );
     1715                otypeParams.emplace_back( alignParam );
     1716
     1717                if ( auto * polyStruct =
     1718                                dynamic_cast<ast::StructInstType const *>( polyType ) ) {
     1719                        // Zero-length arrays are illegal in C, so empty structs have no
     1720                        // offset array.
     1721                        if ( !polyStruct->base->members.empty() ) {
     1722                                ast::ObjectDecl * offsetParam = ast::deepCopy( &newPtr );
     1723                                offsetParam->location = funcParam->location;
     1724                                offsetParam->name = offsetofName( typeName );
     1725                                otypeParams.emplace_back( offsetParam );
     1726                        }
     1727                }
    16101728                seenTypes.insert( typeName );
    1611 
    1612                 auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
    1613                 otypeParams.emplace_back( sizeParam );
    1614 
    1615                 auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
    1616                 otypeParams.emplace_back( alignParam );
    1617 
    1618                 // Zero-length arrays are illegal in C, so empty structs have no
    1619                 // offset array.
    1620                 if ( auto * polyStruct =
    1621                                 dynamic_cast<ast::StructInstType const *>( polyType ) ;
    1622                                 polyStruct && !polyStruct->base->members.empty() ) {
    1623                         auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) );
    1624                         otypeParams.emplace_back( offsetParam );
    1625                 }
    1626         }
    1627 
    1628         // Prepend each argument group. From last group to first. addAdapters
    1629         // does do the same, it just does it itself and see all other parameters.
    1630         spliceBegin( mutDecl->params, inferredParams );
    1631         spliceBegin( mutDecl->params, otypeParams );
    1632         spliceBegin( mutDecl->params, layoutParams );
    1633         addAdapters( mutDecl, localTypeVars );
     1729        }
     1730
     1731        // TODO: A unified way of putting these together might be nice.
     1732        // Put the list together: adapters (in helper) otype parameters,
     1733        // inferred params., layout params. (done) and finally explicit params.
     1734        spliceBegin( inferredParams, otypeParams );
     1735        spliceAt( mutDecl->params, last, inferredParams );
     1736        mutDecl = addAdapters( mutDecl );
    16341737
    16351738        return mutDecl;
    16361739}
    16371740
    1638 ast::FunctionDecl const * DeclAdapter::postvisit(
     1741ast::DeclWithType const * DeclAdapter::postvisit(
    16391742                ast::FunctionDecl const * decl ) {
    16401743        ast::FunctionDecl * mutDecl = mutate( decl );
     
    16701773}
    16711774
    1672 void DeclAdapter::addAdapters(
    1673                 ast::FunctionDecl * mutDecl, TypeVarMap & localTypeVars ) {
    1674         ast::vector<ast::FunctionType> functions;
     1775void DeclAdapter::previsit( ast::CompoundStmt const * ) {
     1776        GuardScope( scopeTypeVars );
     1777        // TODO: It is entirely possible the scope doesn't need to spread
     1778        // across multiple functions. Otherwise, find a better clear.
     1779        std::set<TypeVarMap::key_type> keys;
     1780        for ( auto pair : const_cast<TypeVarMap const &>( scopeTypeVars ) ) {
     1781                keys.insert( pair.first );
     1782        }
     1783        for ( auto key : keys ) {
     1784                scopeTypeVars.erase( key );
     1785        }
     1786}
     1787
     1788// It actually does mutate in-place, but does the return for consistency.
     1789ast::FunctionDecl * DeclAdapter::addAdapters( ast::FunctionDecl * mutDecl ) {
     1790        std::vector<ast::ptr<ast::FunctionType>> functions;
    16751791        for ( ast::ptr<ast::DeclWithType> & arg : mutDecl->params ) {
    16761792                ast::Type const * type = arg->get_type();
    1677                 type = findAndReplaceFunction( type, functions, localTypeVars, needsAdapter );
     1793                type = findAndReplaceFunction( type, functions, scopeTypeVars, needsAdapter );
    16781794                arg.get_and_mutate()->set_type( type );
    16791795        }
    16801796        std::set<std::string> adaptersDone;
    16811797        for ( ast::ptr<ast::FunctionType> const & func : functions ) {
    1682                 std::string mangleName = mangleAdapterName( func, localTypeVars );
     1798                std::string mangleName = mangleAdapterName( func, scopeTypeVars );
    16831799                if ( adaptersDone.find( mangleName ) != adaptersDone.end() ) {
    16841800                        continue;
     
    16881804                mutDecl->params.insert( mutDecl->params.begin(), new ast::ObjectDecl(
    16891805                        mutDecl->location, adapterName,
    1690                         new ast::PointerType( makeAdapterType( func, localTypeVars ) ),
     1806                        new ast::PointerType( makeAdapterType( func, scopeTypeVars ) ),
    16911807                        nullptr, {}, {}, nullptr,
    16921808                        { new ast::Attribute( "unused" ) } ) );
    16931809                adaptersDone.insert( adaptersDone.begin(), mangleName );
    16941810        }
     1811        return mutDecl;
    16951812}
    16961813
     
    18091926        /// Namer for VLA (variable length array) buffers.
    18101927        UniqueName bufNamer;
    1811         /// If the argument of an AddressExpr is MemberExpr, it is stored here.
    1812         ast::MemberExpr const * addrMember = nullptr;
     1928        /// AddressExpr argument is MemberExpr? (TODO: What?)
     1929        ast::Expr const * addrMember = nullptr;
    18131930        /// Used to avoid recursing too deep in type declarations.
    18141931        bool expect_func_type = false;
     
    18421959        beginTypeScope( decl->type );
    18431960
    1844         // TODO: Going though dec->params does not work for some reason.
     1961        // - Tried inserting this code.
     1962        // Make sure that any type information passed into the function is
     1963        // accounted for.
     1964        // TODO: For some reason going through decl->params/->get_type() does
     1965        // not work. Possibly something is not getting updated.
    18451966        for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
    18461967                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     
    18982019ast::StructDecl const * PolyGenericCalculator::previsit(
    18992020                ast::StructDecl const * decl ) {
     2021        //return strict_dynamic_cast<ast::StructDecl *>( mutateMembers( decl ) );
    19002022        auto mutDecl = mutate( decl );
    19012023        mutateMembers( mutDecl );
     
    19052027ast::UnionDecl const * PolyGenericCalculator::previsit(
    19062028                ast::UnionDecl const * decl ) {
     2029        //return strict_dynamic_cast<ast::UnionDecl *>( mutateMembers( decl ) );
    19072030        auto mutDecl = mutate( decl );
    19082031        mutateMembers( mutDecl );
     
    19652088        auto mutDecl = mutate( decl );
    19662089
    1967         // Forally, side effects are not safe in this function. But it works.
     2090        //mutDecl->attributes.remove_if( matchAndMove );
     2091        // TODO: This common helper might work, but does not officially support
     2092        // side effects.
    19682093        erase_if( mutDecl->attributes, matchAndMove );
    19692094
     
    20732198        // the substitution manually. For some reason this is not currently the
    20742199        // case. This requires more investigation.
    2075         ast::ptr<ast::Type> memberType = deepCopy( expr->member->get_type() );
     2200        ast::Type const * memberType = deepCopy( expr->member->get_type() );
    20762201        ast::TypeSubstitution sub = genericSubstitution( objectType );
    2077         sub.apply( memberType );
    2078 
     2202        auto result = sub.apply( memberType );
     2203        memberType = result.node.get(); // .release();
    20792204        // Not all members of a polymorphic type are themselves of a polymorphic
    20802205        // type; in this cas the member expression should be wrapped and
     
    20922217
    20932218void PolyGenericCalculator::previsit( ast::AddressExpr const * expr ) {
     2219        // Is the argument a MemberExpr before mutating?
    20942220        GuardValue( addrMember ) = expr->arg.as<ast::MemberExpr>();
    20952221}
     
    21072233        // MemberExpr was converted to pointer + offset; and it is not valid C to
    21082234        // take the address of an addition, so stript the address-of.
    2109         // It also preserves the env value.
    2110         return ast::mutate_field( expr->arg.get(), &ast::Expr::env, expr->env );
     2235        // TODO: should expr->arg->result be changed to expr->result?
     2236        ast::Expr * ret = mutate( expr->arg.get() );
     2237        ret->env = expr->env;
     2238        return ret;
    21112239}
    21122240
     
    24442572                public BoxPass,
    24452573                public ast::WithGuards {
    2446         void guardTypeVarMap( ast::Type const * type ) {
    2447                 GuardScope( scopeTypeVars );
    2448                 makeTypeVarMap( type, scopeTypeVars );
    2449         }
     2574        template<typename decl_t>
     2575        decl_t const * handleDecl( decl_t const * decl, ast::Type const * type );
    24502576
    24512577        ast::ObjectDecl const * previsit( ast::ObjectDecl const * decl );
     
    24592585};
    24602586
     2587template<typename decl_t>
     2588decl_t const * Eraser::handleDecl(
     2589                decl_t const * decl, ast::Type const * type ) {
     2590        GuardScope( scopeTypeVars );
     2591        makeTypeVarMap( type, scopeTypeVars );
     2592        return scrubAllTypeVars( decl );
     2593}
     2594
    24612595ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {
    2462         guardTypeVarMap( decl->type );
    2463         return scrubAllTypeVars( decl );
     2596        return handleDecl( decl, decl->type );
    24642597}
    24652598
    24662599ast::FunctionDecl const * Eraser::previsit( ast::FunctionDecl const * decl ) {
    2467         guardTypeVarMap( decl->type );
    2468         return scrubAllTypeVars( decl );
     2600        return handleDecl( decl, decl->type );
    24692601}
    24702602
    24712603ast::TypedefDecl const * Eraser::previsit( ast::TypedefDecl const * decl ) {
    2472         guardTypeVarMap( decl->base );
    2473         return scrubAllTypeVars( decl );
     2604        return handleDecl( decl, decl->base );
    24742605}
    24752606
     
    24772608template<typename node_t>
    24782609node_t const * stripGenericMembers( node_t const * decl ) {
    2479         if ( decl->params.empty() ) return decl;
    2480         auto mutDecl = ast::mutate( decl );
    2481         mutDecl->members.clear();
    2482         return mutDecl;
     2610        if ( !decl->params.empty() ) {
     2611                auto mutDecl = ast::mutate( decl );
     2612                mutDecl->members.clear();
     2613                return mutDecl;
     2614        }
     2615        return decl;
    24832616}
    24842617
     
    24962629
    24972630void Eraser::previsit( ast::PointerType const * type ) {
    2498         guardTypeVarMap( type );
     2631        GuardScope( scopeTypeVars );
     2632        makeTypeVarMap( type, scopeTypeVars );
    24992633}
    25002634
    25012635void Eraser::previsit( ast::FunctionType const * type ) {
    2502         guardTypeVarMap( type );
     2636        GuardScope( scopeTypeVars );
     2637        makeTypeVarMap( type, scopeTypeVars );
    25032638}
    25042639
  • src/GenPoly/InstantiateGeneric.h

    rf45772e r2261bcc  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGeneric.h -- Create concrete instances of generic types.
     7// InstantiateGeneric.h --
    88//
    99// Author           : Aaron B. Moss
     
    2424
    2525namespace GenPoly {
    26 
     26/// Replaces all generic types that have static layout with concrete
     27/// instantiations. Types with concrete values for otype parameters will be
     28/// template-expanded, while dtype and ftype parameters will be replaced by
     29/// the appropriate void type.
    2730void instantiateGeneric( std::list< Declaration* > &translationUnit );
    2831void instantiateGeneric( ast::TranslationUnit & translationUnit );
    29 /// Replaces all generic types that have static layout with concrete
    30 /// instantiations. Sized types are replaced with the concrete argument types
    31 /// while unsized types are erased to a void type.
    32 /// This pass can cause designators to ignore the pretty print option.
    33 
    3432} // namespace GenPoly
    3533
  • src/GenPoly/InstantiateGenericNew.cpp

    rf45772e r2261bcc  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGenericNew.cpp -- Create concrete instances of generic types.
     7// InstantiateGenericNew.cpp --
    88//
    99// Author           : Andrew Beach
  • src/Validate/NoIdSymbolTable.hpp

    rf45772e r2261bcc  
    2020namespace Validate {
    2121
    22 // A SymbolTable that only tracks names relevant to Validate passes.
    23 // It tracks type names but not identifier names.
    24 // Some of the canonicalization that occurs before the resolver
    25 // affects how identifier name errors get reported to the user.
    26 // The Validate phase needs to chase type names,
    27 // but it is too early to try tracking identifier names.
    28 // Identifier skipping is acheived by omitting methods that should not be
     22// A SymbolTable that only has the operations used in the Translate Dimension
     23// pass. More importantly, it doesn't have some methods that should no be
    2924// called by the Pass template (lookupId and addId).
    3025class NoIdSymbolTable {
    3126        ast::SymbolTable base;
    3227public:
    33         // All names that are tracked (now) are eligible for collision validation (now).
    34         // (Names that are only tracked later get their collision validation then.)
    35         NoIdSymbolTable() : base(ast::SymbolTable::ValidateOnAdd) {}
    36 
    3728#       define FORWARD_X( func, types_and_names, just_names ) \
    3829        inline auto func types_and_names -> decltype( base.func just_names ) { \
  • src/main.cc

    rf45772e r2261bcc  
    421421                DUMP( bboxp, std::move( transUnit ) );
    422422                PASS( "Box", GenPoly::box, transUnit );
    423                 PASS( "Link-Once", CodeGen::translateLinkOnce, transUnit );
    424423
    425424                translationUnit = convert( std::move( transUnit ) );
     425
     426                PASS( "Link-Once", CodeGen::translateLinkOnce, translationUnit );
    426427
    427428                // Code has been lowered to C, now we can start generation.
  • tests/collections/.expect/string-istream-manip.txt

    rf45772e r2261bcc  
    1 preS1 0123456
    2 preS1 x
    3 preS2 01234567
    4 preS2 x
    5 preS3 012345678
    6 preS3 x
    7 preS4 0123456789
    8 preS4 x
    9 preSMN1 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456
    10 preSMN1 x
    11 preSMN2 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567
    12 preSMN2 x
    13 preSMN3 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678
    14 preSMN3 x
    15 preSMN4 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789
    16 preSMN4 x
    17 preRMN1 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456
    18 preRMN1 x
    19 preRMN2 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567
    20 preRMN2 x
    21 preRMN3 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678
    22 preRMN3 x
    23 preRMN4 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789
    24 preRMN4 x
    25 preSMI1 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...       "
    26 preSMI1 "x"
    27 preSMI2 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...        "
    28 preSMI2 "x"
    29 preSMI3 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...         "
    30 preSMI3 "x"
    31 preSMI4 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...          "
    32 preSMI4 "x"
    33 preSME1 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...       "
    34 preSME1 "x"
    35 preSME2 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...        "
    36 preSME2 "x"
    37 preSME3 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...         "
    38 preSME3 "x"
    39 preSME4 "...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...          "
    40 preSME4 "x"
    41 preSMG1 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456
    42 preSMG1 x
    43 preSMG2 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567
    44 preSMG2 x
    45 preSMG3 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678
    46 preSMG3 x
    47 preSMG4 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789
    48 preSMG4 x
    49 preSMD1 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456
    50 preSMD1 x
    51 preSMD2 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567
    52 preSMD2 x
    53 preSMD3 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678
    54 preSMD3 x
    55 preSMD4 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789
    56 preSMD4 x
    5711 yyyyyyyyyyyyyyyyyyyy
    5822 abcxxx
     
    681212 wwwwwwww
    691313 wwwwwwww
    70 14 cccc
    71 15
    72141 yyyyyyyyyyyyyyyyyyyy
    73152 abcxxx
     
    832512 wwwwwwww
    842613 wwwwwwww
    85 14 cccc
    86 15
  • tests/collections/.in/string-istream-manip.txt

    rf45772e r2261bcc  
    1 0123456 x
    2 01234567 x
    3 012345678 x
    4 0123456789 x
    5 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456 x
    6 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567 x
    7 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678 x
    8 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789 x
    9 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456 x
    10 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567 x
    11 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678 x
    12 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789 x
    13 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...       -x-
    14 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...        -x-
    15 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...         -x-
    16 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...          -x-
    17 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...       -x-
    18 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...        -x-
    19 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...         -x-
    20 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...          -x-
    21 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456
    22 x
    23 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567
    24 x
    25 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678
    26 x
    27 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789
    28 x
    29 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456@x@
    30 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567@x@
    31 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678@x@
    32 ...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789@x@
    331abc
    34 cccccb
     2abc
    353xx
    364abcxxx
    375abcyyy
    386aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
    39 uuuuuccccuuuuu
    407abc
    41 cccccb
     8abc
    429xx
    4310abcxxx
    4411abcyyy
    4512aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
    46 uuuuuccccuuuuu
  • tests/collections/string-istream-manip.cfa

    rf45772e r2261bcc  
    33#include <collections/string.hfa>
    44#include <collections/string_res.hfa>
    5 #include <stdio.h>
    6 
    7 // No-op manipulators.
    8 // Temporary hack while there are two code paths in the string implementation.
    9 // (One for reading plain strings, the other for reading via a manipulator.)
    10 // The test cases that use plainjane(-) are exercising the via-manipulator code path,
    11 // just with trivial manipulation.
    12 static _Istream_Sstr plainjane( string     & s )  { return (_Istream_Sstr)@{  s, {{0p}, -1, {.flags.rwd : false}} }; }
    13 static _Istream_Rstr plainjane( string_res & s )  { return (_Istream_Rstr)@{ &s, {{0p}, -1, {.flags.rwd : false}} }; }
    14 
    15 static void forceStringHeapFreeSpaceTo(int desiredSize) {
    16     for (1_000_000) {
    17         string x = "a";
    18         (void)x;
    19       if (desiredSize == DEBUG_string_bytes_avail_until_gc(DEBUG_string_heap())) return;
    20     }
    21     sout | "Unable to force size" | desiredSize | "in 1,000,000 tries";
    22 }
    235
    246int main() {
    25     // These "pre" cases deal with issues analogous to the "pre" cases of io/manipulatorsInput.
    26     // The acceptance criterion is simpler but driving the cases is harder.
    27     // The tests just read strings and echo what they read; acceptance of simple echoing assures
    28     // no spurious splitting merging.
    29     // The lengths of the strings are chosen to match white-box knowledge of when the string layer
    30     // has tor drive the cstring layer through a second iteration:
    31     //  - for no-manip, lengths are near the room at end of string heap
    32     //    (chosen target size of 9 showed the original bug on preS2, aligned with the other cases)
    33     //  - for manip, lengths are near the auxiliary buffer size of 128
    34     // Only first case repeats for string_res; rest run only from the passthru string layer.
    35     // Similarly, the manipulator breadth isn't checked at the cstring layer either.
    36     {
    37         // S: string, no manipulator
    38         void echoTillX(const char * casename) {
    39             string s;
    40             do {
    41                 forceStringHeapFreeSpaceTo(9);
    42                 sin | s;
    43                 sout | casename | s;
    44             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    45         }
    46         echoTillX("preS1");
    47         echoTillX("preS2");
    48         echoTillX("preS3");
    49         echoTillX("preS4");
    50     }
    51     {
    52         // SMN: string, manipulator for no-op
    53         void echoTillX(const char * casename) {
    54             string s;
    55             do {
    56                 sin | plainjane( s );
    57                 sout | casename | s;
    58             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    59         }
    60         echoTillX("preSMN1");
    61         echoTillX("preSMN2");
    62         echoTillX("preSMN3");
    63         echoTillX("preSMN4");
    64     }
    65     {
    66         // RMN: string_res, manipulator for no-op
    67         void echoTillX(const char * casename) {
    68             string_res s;
    69             do {
    70                 sin | plainjane( s );
    71                 sout | casename | s;
    72             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    73         }
    74         echoTillX("preRMN1");
    75         echoTillX("preRMN2");
    76         echoTillX("preRMN3");
    77         echoTillX("preRMN4");
    78     }
    79     {
    80         // SMI: string, manipulator `incl`
    81         void echoTillX(const char * casename) {
    82             string s;
    83             do {
    84                 sin | skip("-\n");
    85                 sin | incl( ".:|# x", s );
    86                 sout | casename | " \"" | s | "\"";
    87             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    88         }
    89         echoTillX("preSMI1");
    90         echoTillX("preSMI2");
    91         echoTillX("preSMI3");
    92         echoTillX("preSMI4");
    93     }
    94     {
    95         // SME: string, manipulator `excl`
    96         void echoTillX(const char * casename) {
    97             string s;
    98             do {
    99                 sin | skip("-\n");
    100                 sin | excl( "-\n", s );
    101                 sout | casename | " \"" | s | "\"";
    102             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    103         }
    104         echoTillX("preSME1");
    105         echoTillX("preSME2");
    106         echoTillX("preSME3");
    107         echoTillX("preSME4");
    108     }
    109     sin | skip("-\n");
    110     {
    111         // SMG: string, manipulator `getline`
    112         void echoTillX(const char * casename) {
    113             string s;
    114             do {
    115                 sin | getline( s );
    116                 sout | casename | s;
    117             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    118         }
    119         echoTillX("preSMG1");
    120         echoTillX("preSMG2");
    121         echoTillX("preSMG3");
    122         echoTillX("preSMG4");
    123     }
    124     {
    125         // SMD: string, manipulator (`getline` with custom) delimiter
    126         void echoTillX(const char * casename) {
    127             string s;
    128             do {
    129                 sin | getline( s, '@' );
    130                 sout | casename | s;
    131             } while ( size(s) > 0 && s[size(s)-1] != 'x' );
    132             sin | skip(" \n");
    133         }
    134         echoTillX("preSMD1");
    135         echoTillX("preSMD2");
    136         echoTillX("preSMD3");
    137         echoTillX("preSMD4");
    138     }
    139 
    1407    /* Keep harmonized with io/manipulatorsInput */
    1418    {
     
    15623        sin | ignore( incl( "abc", wdi( 8, s ) ) );     sout | "12" | s;
    15724        sin | ignore( excl( "abc", wdi( 8, s ) ) );     sout | "13" | s;
    158 
    159                 s = "q";
    160                 sin | incl( "abc", s );                         sout | "14" | s;
    161                 s = "q";
    162                 sin | excl( "u", s );                           sout | "15" | s;
    163                 sin | skip( "u" );
    164                 sin | "\n";
    165         }
    166     // Full repeat on string_res layer assures the full manipulator vocabulary is supported there.
     25    }
    16726    {
    16827        string_res s = "yyyyyyyyyyyyyyyyyyyy";
     
    18241        sin | ignore( incl( "abc", wdi( 8, s ) ) );     sout | "12" | s;
    18342        sin | ignore( excl( "abc", wdi( 8, s ) ) );     sout | "13" | s;
    184 
    185                 s = "q";
    186                 sin | incl( "abc", s );                         sout | "14" | s;
    187                 s = "q";
    188                 sin | excl( "u", s );                           sout | "15" | s;
    189                 sin | skip( "u" );
    190                 sin | "\n";
    19143    }
    19244}
  • tests/errors/.expect/scope.txt

    rf45772e r2261bcc  
    1 errors/scope.cfa:13:1 error: duplicate object definition for thisIsAnError: signed int
    2 errors/scope.cfa:30:1 error: duplicate function definition for butThisIsAnError: function
     1errors/scope.cfa:2:1 error: duplicate object definition for thisIsAnError: signed int
     2errors/scope.cfa:20:1 error: duplicate function definition for butThisIsAnError: function
    33... with parameters
    44  double
  • tests/errors/scope.cfa

    rf45772e r2261bcc  
    1 // Keep harmonized with errors/scope.
     1int thisIsAnError;
     2int thisIsAnError;
    23
    3 #ifdef OMIT_DRIVING_REJECTIONS
    4 // For manual sanity checking:
    5 // Leave out the offensive declarations and verify that what's left is accepted.
    6 #define EXPREJ(...)
    7 #else
    8 #define EXPREJ(...) __VA_ARGS__
    9 #endif
     4int thisIsNotAnError;
     5float thisIsNotAnError;
    106
     7int thisIsAlsoNotAnError() {
     8  int thisIsNotAnError;
     9}
    1110
    12         int thisIsAnError;
    13 EXPREJ( int thisIsAnError; )
     11int thisIsAlsoNotAnError( double x ) {
     12}
    1413
    15         int thisIsNotAnError;
    16         float thisIsNotAnError;
     14double thisIsStillNotAnError( double );
     15double thisIsStillNotAnError( double );
    1716
    18         int thisIsAlsoNotAnError() {
    19           int thisIsNotAnError;
    20         }
     17double butThisIsAnError( double ) {
     18}
    2119
    22         int thisIsAlsoNotAnError( double x ) {
    23         }
    24 
    25         double thisIsStillNotAnError( double );
    26         double thisIsStillNotAnError( double );
    27 
    28         double butThisIsAnError( double ) {
    29         }
    30 EXPREJ(
    31         double butThisIsAnError( double ) {
    32         }
    33 )
     20double butThisIsAnError( double ) {
     21}
    3422
    3523// Local Variables: //
  • tests/io/.expect/manipulatorsInput.arm64.txt

    rf45772e r2261bcc  
    11pre1 "123456", canary ok
    2 pre2 "1234567", canary ok
    3 pre3a "1234567", exception occurred, canary ok
    4 pre3b "8", canary ok
    5 pre4a "1234567", exception occurred, canary ok
    6 pre4b "89", canary ok
     2pre2a "1234567", exception occurred, canary ok
     3pre2b "89", canary ok
    741 yyyyyyyyyyyyyyyyyyyy
    852 abcxxx
     
    181512 wwwwwwww
    191613 wwwwwwww
    20 14 rc=1, cccc
    21 15 rc=0, q
    22171 yyyyyyyyyyyyyyyyyyyy
    23182 abcxxx
     
    332812 wwwwwwww
    342913 wwwwwwww
    35 14 cccc
    36 15
    3730a
    3831a
  • tests/io/.expect/manipulatorsInput.x64.txt

    rf45772e r2261bcc  
    11pre1 "123456", canary ok
    2 pre2 "1234567", canary ok
    3 pre3a "1234567", exception occurred, canary ok
    4 pre3b "8", canary ok
    5 pre4a "1234567", exception occurred, canary ok
    6 pre4b "89", canary ok
     2pre2a "1234567", exception occurred, canary ok
     3pre2b "89", canary ok
    741 yyyyyyyyyyyyyyyyyyyy
    852 abcxxx
     
    181512 wwwwwwww
    191613 wwwwwwww
    20 14 rc=1, cccc
    21 15 rc=0, q
    22171 yyyyyyyyyyyyyyyyyyyy
    23182 abcxxx
     
    332812 wwwwwwww
    342913 wwwwwwww
    35 14 cccc
    36 15
    3730a
    3831a
  • tests/io/.expect/manipulatorsInput.x86.txt

    rf45772e r2261bcc  
    11pre1 "123456", canary ok
    2 pre2 "1234567", canary ok
    3 pre3a "1234567", exception occurred, canary ok
    4 pre3b "8", canary ok
    5 pre4a "1234567", exception occurred, canary ok
    6 pre4b "89", canary ok
     2pre2a "1234567", exception occurred, canary ok
     3pre2b "89", canary ok
    741 yyyyyyyyyyyyyyyyyyyy
    852 abcxxx
     
    181512 wwwwwwww
    191613 wwwwwwww
    20 14 rc=1, cccc
    21 15 rc=0, q
    22171 yyyyyyyyyyyyyyyyyyyy
    23182 abcxxx
     
    332812 wwwwwwww
    342913 wwwwwwww
    35 14 cccc
    36 15
    3730a
    3831a
  • tests/io/.in/manipulatorsInput.txt

    rf45772e r2261bcc  
    11123456
    2 1234567
    3 12345678
    42123456789
    53abc
    6 cccccb
     4abc
    75xx
    86abcxxx
    97abcyyy
    108aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
    11 uuuuuccccuuuuu
    129abc
    13 cccccb
     10abc
    1411xx
    1512abcxxx
    1613abcyyy
    1714aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
    18 uuuuuccccuuuuu
    1915ab
    20160xff 017 15-15
  • tests/io/manipulatorsInput.cfa

    rf45772e r2261bcc  
    4545                }
    4646
    47                 rep("pre1");    // 123456     |  123456
    48                 rep("pre2");    // 1234567    |  1234567
    49                 rep("pre3a");   // 12345678   |  1234567
    50                 rep("pre3b");   //            |  8
    51                 rep("pre4a");   // 123456789  |  1234567
    52                 rep("pre4b");   //            |  89
    53 
     47                rep("pre1");
     48                rep("pre2a");
     49                rep("pre2b");
    5450                scanf("\n");  // next test does not start with %s so does not tolerate leading whitespace
    5551        }
    5652        {
    5753                char s[] = "yyyyyyyyyyyyyyyyyyyy";
    58                 const char sk_fmt[] = "%*[abc]";
    59                 scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s );
     54                const char sk[] = "abc";
     55                scanf( "abc " ); scanf( sk ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s );
    6056                scanf( "%s", s );                                                               printf( "2 %s\n", s );
    6157                scanf( "%*s" );                                                                 printf( "3 %s\n", s );
     
    7167                scanf( "%*8[abc]" );                                                    printf( "12 %s\n", s );
    7268                scanf( "%*8[^abc]" );                                                   printf( "13 %s\n", s );
    73 
    74                 int rc;
    75                 s[0] = 'q'; s[1] = '\0'; rc = 99;
    76                 rc = scanf( "%[abc]", s );                                              printf( "14 rc=%d, %s\n", rc, s );
    77                 s[0] = 'q'; s[1] = '\0'; rc = 99;
    78                 rc = scanf( "%[^u]", s );                                               printf( "15 rc=%d, %s\n", rc, s );
    79                 scanf( "%*[u]" );
    80                 scanf("\n");
    8169        }
    8270        {
     
    9785                sin | ignore( incl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "12" | s;
    9886                sin | ignore( excl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "13" | s;
    99 
    100                 s[0] = 'q'; s[1] = '\0';
    101                 sin | incl( "abc", wdi( sizeof(s), s ) );               sout | "14" | s;
    102                 s[0] = 'q'; s[1] = '\0';
    103                 sin | excl( "u", wdi( sizeof(s), s ) );                 sout | "15" | s;
    104                 sin | skip( "u" );
    105                 sin | "\n";
    10687        }
    10788    /* Keep harmonized with collections/string-istream-manip */
  • tests/test.py

    rf45772e r2261bcc  
    116116        parser.add_argument('--no-invariant', help='Tell the compiler not to check invariants.', action='store_false', dest='invariant')
    117117        parser.add_argument('--invariant', help='Tell the compiler to check invariants.', action='store_const', const=True)
    118         parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=240)
     118        parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=180)
    119119        parser.add_argument('--global-timeout', help='Maximum cumulative duration in seconds after the ALL tests are considered to have timed out', type=int, default=7200)
    120120        parser.add_argument('--timeout-with-gdb', help='Instead of killing the command when it times out, orphan it and print process id to allow gdb to attach', type=yes_no, default="no")
  • tools/build/cfa.m4

    rf45772e r2261bcc  
    6767                "x86_64"     ) cannon_arch_name="x64";;
    6868                "aarch64"    ) cannon_arch_name="arm64";;
    69                 "arm64"      ) cannon_arch_name="arm64";;
     69                "arm4"       ) cannon_arch_name="arm64";;
    7070                "ARM64"      ) cannon_arch_name="arm64";;
    7171                "x86"        ) cannon_arch_name="x86";;
Note: See TracChangeset for help on using the changeset viewer.