Changeset f45772e


Ignore:
Timestamp:
Oct 8, 2023, 9:14:31 AM (12 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
92211d9
Parents:
2261bcc (diff), 9689e54 (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

Files:
2 added
23 edited

Legend:

Unmodified
Added
Removed
  • Jenkins/FullBuild

    r2261bcc rf45772e  
    2525                                        gcc_08_x64_new: { trigger_build( 'gcc-8',   'x64', false ) },
    2626                                        gcc_07_x64_new: { trigger_build( 'gcc-7',   'x64', false ) },
    27                                         // gcc_06_x64_new: { trigger_build( 'gcc-6',   '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 ) },
    2831                                        clang_x64_new:  { trigger_build( 'clang',   'x64', true  ) },
    2932                                )
  • Jenkins/TestRegen

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

    r2261bcc rf45772e  
    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 (;;) {
     220    for (bool cont = true; cont; ) {
     221        cont = false;
     222
    221223        // Append dummy content to temp, forcing expansion when applicable (occurs always on subsequent loops)
    222224        // length 2 ensures room for at least one real char, plus scanf/pipe-cstr's null terminator
     
    228230        temp.Handle.ulink->EndVbyte -= 2;
    229231
    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);
     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);
    233235
    234236        // get bytes
    235         in | wdi( lenReadable + 1, lenReadable, temp.Handle.ulink->EndVbyte );
     237        try {
     238            in | wdi( lenReadable, temp.Handle.ulink->EndVbyte );
     239        } catch (cstring_length*) {
     240            cont = true;
     241        }
    236242        int lenWasRead = strlen(temp.Handle.ulink->EndVbyte);
    237243
     
    239245        temp.Handle.lnth += lenWasRead;
    240246        temp.Handle.ulink->EndVbyte += lenWasRead;
    241 
    242       if (lenWasRead < lenReadable) break;
    243247    }
    244248
  • libcfa/src/iostream.cfa

    r2261bcc rf45772e  
    2222#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
    2323#include <complex.h>                                                                    // creal, cimag
     24#include <ctype.h>                                                                              // isspace
    2425//#include <stdio.h>
    2526
     
    2930extern char *strcpy (char *__restrict __dest, const char *__restrict __src) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
    3031extern void *memcpy (void *__restrict __dest, const void *__restrict __src, size_t __n) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1, 2)));
     32extern char *strchr(const char *str, int ch);
    3133} // extern "C"
    3234
     
    960962        istype & ?|?( istype & is, _Istream_Cskip f ) {
    961963                // printf( "skip %s %d\n", f.scanset, f.wd );
    962                 if ( f.scanset ) fmt( is, f.scanset, "" );              // no input arguments
     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                }
    963976                else for ( f.wd ) fmt( is, "%*c" );
    964977                return is;
     
    980993                        // wd is buffer bytes available (for input chars + null terminator)
    981994                        // rwd is count of input chars
    982                         int rwd = f.flags.rwd ? f.wd : (f.wd - 1);
     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
    9831003                        start += sprintf( &fmtstr[start], "%d", rwd );
    9841004                }
     
    10001020
    10011021                int check = f.wd - 2;
    1002                 if ( ! f.flags.rwd ) f.s[check] = '\0';                 // insert sentinel
     1022                if (! f.flags.ignore ) {
     1023                        f.s[0] = '\0';
     1024                        if ( ! f.flags.rwd ) f.s[check] = '\0';         // insert sentinel
     1025                }
    10031026                len = fmt( is, fmtstr, f.s );
    10041027                //fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, f.s[check], f.s );
    10051028
    1006                 if ( ! f.flags.rwd && f.s[check] != '\0' )              // sentinel overwritten ?
    1007                         throw (cstring_length){ &cstring_length_vt };
     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
    10081047
    10091048                if ( f.flags.delimiter ) {                                              // getline ?
  • src/CodeGen/LinkOnce.cc

    r2261bcc rf45772e  
    1010// Created On       : Thur May 13 10:10:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thur May 13 14:39:00 2021
    13 // Update Count     : 0
     12// Last Modified On : Wed Oct  4 10:52:00 2023
     13// Update Count     : 1
    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"
    2024#include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
    2125
    2226namespace CodeGen {
    2327
    24 static bool is_cfa_linkonce( Attribute const * attr ) {
     28namespace {
     29
     30bool is_cfa_linkonce_old( Attribute const * attr ) {
    2531        return std::string("cfa_linkonce") == attr->name;
    2632}
    2733
    28 static bool is_section_attribute( Attribute const * attr ) {
     34bool is_section_attribute_old( Attribute const * attr ) {
    2935        return std::string("section") == attr->name;
    3036}
     
    3945                std::list< Attribute * > & attributes = decl->attributes;
    4046                // See if we can find the element:
    41                 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce );
     47                auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old );
    4248                if ( attributes.end() != found ) {
    4349                        // Remove any other sections:
    44                         attributes.remove_if( is_section_attribute );
     50                        attributes.remove_if( is_section_attribute_old );
    4551                        // Iterator to the cfa_linkonce attribute should still be valid.
    4652                        Attribute * attribute = *found;
     
    6369};
    6470
     71bool is_cfa_linkonce( ast::Attribute const * attr ) {
     72        return "cfa_linkonce" == attr->name;
     73}
     74
     75bool is_section_attribute( ast::Attribute const * attr ) {
     76        return "section" == attr->name;
     77}
     78
     79struct 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
    65124void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
    66125        PassVisitor<LinkOnceVisitorCore> translator;
     
    68127}
    69128
     129void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
     130        ast::Pass<LinkOnceCore>::run( translationUnit );
    70131}
     132
     133} // namespace CodeGen
  • src/CodeGen/LinkOnce.h

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

    r2261bcc rf45772e  
    7777};
    7878
    79 // Formally takeOtypeOnly
    8079/// Get all sized type declarations; those that affect a layout function.
    8180ast::vector<ast::TypeDecl> takeSizedParams(
     
    510509                ast::FunctionType const * function,
    511510                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 
    517511        // If the return type or a parameter type involved polymorphic types,
    518512        // then the adapter will need to take those polymorphic types as pointers.
     
    587581        ast::FunctionType const * type = decl->type;
    588582        if ( isDynRet( type ) && decl->linkage != ast::Linkage::C ) {
    589                 //retval = type->returns.front();
    590583                retval = decl->returns.front();
    591584
     
    748741ast::Expr const * CallAdapter::postvisit( ast::UntypedExpr const * expr ) {
    749742        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;
    755743                return expr->args.front();
    756744        }
     
    10631051                ast::ptr<ast::Type> newType = ast::deepCopy( param );
    10641052                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 );
    10691053                ast::ObjectDecl * newObj = makeTemporary( location, newType );
    10701054                auto assign = ast::UntypedExpr::createCall( location, "?=?", {
     
    12451229                        }
    12461230                        return new ast::ObjectDecl( location, pNamer.newName(), param );
    1247                 } ), // params
     1231                } ),
    12481232                map_range<ast::vector<ast::DeclWithType>>( adapterType->returns,
    12491233                                [&rNamer, &location]( ast::ptr<ast::Type> const & retval ) {
    12501234                        return new ast::ObjectDecl( location, rNamer.newName(), retval );
    1251                 } ), // returns
     1235                } ),
    12521236                nullptr, // stmts
    1253                 ast::Storage::Classes(), // storage
    1254                 ast::Linkage::C // linkage
    1255                 // attrs
    1256                 // fs
    1257                 // isVarArgs
     1237                {}, // storage
     1238                ast::Linkage::C
    12581239        );
    12591240
     
    13141295        // Returns a polymorphic type.
    13151296        } 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                 }
    13251297                ast::UntypedExpr * assign = new ast::UntypedExpr( location,
    13261298                        new ast::NameExpr( location, "?=?" ) );
     
    15461518
    15471519// --------------------------------------------------------------------------
    1548 /// Creates the adapter functions. TODO
     1520/// Modifies declarations to accept implicit parameters.
    15491521/// * Move polymorphic returns in function types to pointer-type parameters.
    15501522/// * Adds type size and assertion parameters to parameter lists.
    1551 struct 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 );
     1523struct DeclAdapter final {
    15621524        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
    1563         ast::DeclWithType const * postvisit( ast::FunctionDecl const * decl );
    1564         void previsit( ast::CompoundStmt const * stmt );
     1525        ast::FunctionDecl const * postvisit( ast::FunctionDecl const * decl );
    15651526private:
    1566         ast::FunctionDecl * addAdapters( ast::FunctionDecl * decl );
    1567 
    1568         std::map<UniqueId, std::string> adapterName;
     1527        void addAdapters( ast::FunctionDecl * decl, TypeVarMap & localTypeVars );
    15691528};
    15701529
    1571 // at must point within [dst.begin(), dst.end()].
    1572 template< typename T >
    1573 void 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 
    1594 void DeclAdapter::previsit( ast::StructDecl const * ) {
    1595         // Prevent type vars from leaking into the containing scope.
    1596         GuardScope( scopeTypeVars );
    1597 }
    1598 
    1599 void DeclAdapter::previsit( ast::UnionDecl const * ) {
    1600         // Prevent type vars from leaking into the containing scope.
    1601         GuardScope( scopeTypeVars );
    1602 }
    1603 
    1604 void DeclAdapter::previsit( ast::TraitDecl const * ) {
    1605         // Prevent type vars from leaking into the containing scope.
    1606         GuardScope( scopeTypeVars );
    1607 }
    1608 
    1609 void DeclAdapter::previsit( ast::TypeDecl const * decl ) {
    1610         addToTypeVarMap( decl, scopeTypeVars );
    1611 }
    1612 
    1613 void DeclAdapter::previsit( ast::PointerType const * type ) {
    1614         GuardScope( scopeTypeVars );
    1615         makeTypeVarMap( type, scopeTypeVars );
    1616 }
    1617 
    1618 // TODO: I think this code is redundent.
    1619 void DeclAdapter::previsit( ast::FunctionType const * type ) {
    1620         GuardScope( scopeTypeVars );
    1621         makeTypeVarMap( type, scopeTypeVars );
     1530// size/align/offset parameters may not be used, so add the unused attribute.
     1531ast::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
     1539ast::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 );
    16221544}
    16231545
    16241546ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    1625         GuardScope( scopeTypeVars );
    1626         makeTypeVarMap( decl, scopeTypeVars );
     1547        TypeVarMap localTypeVars = { ast::TypeData() };
     1548        makeTypeVarMap( decl, localTypeVars );
    16271549
    16281550        auto mutDecl = mutate( decl );
     
    16391561
    16401562        // Add size/align and assertions for type parameters to parameter list.
    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 );
     1563        ast::vector<ast::DeclWithType> inferredParams;
     1564        ast::vector<ast::DeclWithType> layoutParams;
    16541565        for ( ast::ptr<ast::TypeDecl> & typeParam : mutDecl->type_params ) {
    16551566                auto mutParam = mutate( typeParam.get() );
    16561567                // Add all size and alignment parameters to parameter list.
    16571568                if ( mutParam->isComplete() ) {
    1658                         //ast::TypeInstType paramType( typeParam->name, typeParam );
    16591569                        ast::TypeInstType paramType( mutParam );
    16601570                        std::string paramName = Mangle::mangleType( &paramType );
    16611571
    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;
     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 );
    16731577                }
    16741578                // TODO: These should possibly all be gone.
     
    16961600        // Add size/align for generic parameter types to parameter list.
    16971601        std::set<std::string> seenTypes;
    1698         std::vector<ast::ptr<ast::DeclWithType>> otypeParams;
     1602        ast::vector<ast::DeclWithType> otypeParams;
    16991603        for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
    1700                 ast::Type const * polyType = isPolyType( funcParam->get_type(), scopeTypeVars );
     1604                ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
    17011605                if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
    17021606                        continue;
     
    17041608                std::string typeName = Mangle::mangleType( polyType );
    17051609                if ( seenTypes.count( typeName ) ) continue;
    1706 
    1707                 ast::ObjectDecl * sizeParam = ast::deepCopy( &newObj );
    1708                 sizeParam->location = funcParam->location;
    1709                 sizeParam->name = sizeofName( typeName );
     1610                seenTypes.insert( typeName );
     1611
     1612                auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
    17101613                otypeParams.emplace_back( sizeParam );
    17111614
    1712                 ast::ObjectDecl * alignParam = ast::deepCopy( &newObj );
    1713                 alignParam->location = funcParam->location;
    1714                 alignParam->name = alignofName( typeName );
     1615                auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
    17151616                otypeParams.emplace_back( alignParam );
    17161617
     1618                // Zero-length arrays are illegal in C, so empty structs have no
     1619                // offset array.
    17171620                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                 }
    1728                 seenTypes.insert( typeName );
    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 );
     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 );
    17371634
    17381635        return mutDecl;
    17391636}
    17401637
    1741 ast::DeclWithType const * DeclAdapter::postvisit(
     1638ast::FunctionDecl const * DeclAdapter::postvisit(
    17421639                ast::FunctionDecl const * decl ) {
    17431640        ast::FunctionDecl * mutDecl = mutate( decl );
     
    17731670}
    17741671
    1775 void 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.
    1789 ast::FunctionDecl * DeclAdapter::addAdapters( ast::FunctionDecl * mutDecl ) {
    1790         std::vector<ast::ptr<ast::FunctionType>> functions;
     1672void DeclAdapter::addAdapters(
     1673                ast::FunctionDecl * mutDecl, TypeVarMap & localTypeVars ) {
     1674        ast::vector<ast::FunctionType> functions;
    17911675        for ( ast::ptr<ast::DeclWithType> & arg : mutDecl->params ) {
    17921676                ast::Type const * type = arg->get_type();
    1793                 type = findAndReplaceFunction( type, functions, scopeTypeVars, needsAdapter );
     1677                type = findAndReplaceFunction( type, functions, localTypeVars, needsAdapter );
    17941678                arg.get_and_mutate()->set_type( type );
    17951679        }
    17961680        std::set<std::string> adaptersDone;
    17971681        for ( ast::ptr<ast::FunctionType> const & func : functions ) {
    1798                 std::string mangleName = mangleAdapterName( func, scopeTypeVars );
     1682                std::string mangleName = mangleAdapterName( func, localTypeVars );
    17991683                if ( adaptersDone.find( mangleName ) != adaptersDone.end() ) {
    18001684                        continue;
     
    18041688                mutDecl->params.insert( mutDecl->params.begin(), new ast::ObjectDecl(
    18051689                        mutDecl->location, adapterName,
    1806                         new ast::PointerType( makeAdapterType( func, scopeTypeVars ) ),
     1690                        new ast::PointerType( makeAdapterType( func, localTypeVars ) ),
    18071691                        nullptr, {}, {}, nullptr,
    18081692                        { new ast::Attribute( "unused" ) } ) );
    18091693                adaptersDone.insert( adaptersDone.begin(), mangleName );
    18101694        }
    1811         return mutDecl;
    18121695}
    18131696
     
    19261809        /// Namer for VLA (variable length array) buffers.
    19271810        UniqueName bufNamer;
    1928         /// AddressExpr argument is MemberExpr? (TODO: What?)
    1929         ast::Expr const * addrMember = nullptr;
     1811        /// If the argument of an AddressExpr is MemberExpr, it is stored here.
     1812        ast::MemberExpr const * addrMember = nullptr;
    19301813        /// Used to avoid recursing too deep in type declarations.
    19311814        bool expect_func_type = false;
     
    19591842        beginTypeScope( decl->type );
    19601843
    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.
     1844        // TODO: Going though dec->params does not work for some reason.
    19661845        for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
    19671846                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     
    20191898ast::StructDecl const * PolyGenericCalculator::previsit(
    20201899                ast::StructDecl const * decl ) {
    2021         //return strict_dynamic_cast<ast::StructDecl *>( mutateMembers( decl ) );
    20221900        auto mutDecl = mutate( decl );
    20231901        mutateMembers( mutDecl );
     
    20271905ast::UnionDecl const * PolyGenericCalculator::previsit(
    20281906                ast::UnionDecl const * decl ) {
    2029         //return strict_dynamic_cast<ast::UnionDecl *>( mutateMembers( decl ) );
    20301907        auto mutDecl = mutate( decl );
    20311908        mutateMembers( mutDecl );
     
    20881965        auto mutDecl = mutate( decl );
    20891966
    2090         //mutDecl->attributes.remove_if( matchAndMove );
    2091         // TODO: This common helper might work, but does not officially support
    2092         // side effects.
     1967        // Forally, side effects are not safe in this function. But it works.
    20931968        erase_if( mutDecl->attributes, matchAndMove );
    20941969
     
    21982073        // the substitution manually. For some reason this is not currently the
    21992074        // case. This requires more investigation.
    2200         ast::Type const * memberType = deepCopy( expr->member->get_type() );
     2075        ast::ptr<ast::Type> memberType = deepCopy( expr->member->get_type() );
    22012076        ast::TypeSubstitution sub = genericSubstitution( objectType );
    2202         auto result = sub.apply( memberType );
    2203         memberType = result.node.get(); // .release();
     2077        sub.apply( memberType );
     2078
    22042079        // Not all members of a polymorphic type are themselves of a polymorphic
    22052080        // type; in this cas the member expression should be wrapped and
     
    22172092
    22182093void PolyGenericCalculator::previsit( ast::AddressExpr const * expr ) {
    2219         // Is the argument a MemberExpr before mutating?
    22202094        GuardValue( addrMember ) = expr->arg.as<ast::MemberExpr>();
    22212095}
     
    22332107        // MemberExpr was converted to pointer + offset; and it is not valid C to
    22342108        // take the address of an addition, so stript the address-of.
    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;
     2109        // It also preserves the env value.
     2110        return ast::mutate_field( expr->arg.get(), &ast::Expr::env, expr->env );
    22392111}
    22402112
     
    25722444                public BoxPass,
    25732445                public ast::WithGuards {
    2574         template<typename decl_t>
    2575         decl_t const * handleDecl( decl_t const * decl, ast::Type const * type );
     2446        void guardTypeVarMap( ast::Type const * type ) {
     2447                GuardScope( scopeTypeVars );
     2448                makeTypeVarMap( type, scopeTypeVars );
     2449        }
    25762450
    25772451        ast::ObjectDecl const * previsit( ast::ObjectDecl const * decl );
     
    25852459};
    25862460
    2587 template<typename decl_t>
    2588 decl_t const * Eraser::handleDecl(
    2589                 decl_t const * decl, ast::Type const * type ) {
    2590         GuardScope( scopeTypeVars );
    2591         makeTypeVarMap( type, scopeTypeVars );
     2461ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {
     2462        guardTypeVarMap( decl->type );
    25922463        return scrubAllTypeVars( decl );
    25932464}
    25942465
    2595 ast::ObjectDecl const * Eraser::previsit( ast::ObjectDecl const * decl ) {
    2596         return handleDecl( decl, decl->type );
    2597 }
    2598 
    25992466ast::FunctionDecl const * Eraser::previsit( ast::FunctionDecl const * decl ) {
    2600         return handleDecl( decl, decl->type );
     2467        guardTypeVarMap( decl->type );
     2468        return scrubAllTypeVars( decl );
    26012469}
    26022470
    26032471ast::TypedefDecl const * Eraser::previsit( ast::TypedefDecl const * decl ) {
    2604         return handleDecl( decl, decl->base );
     2472        guardTypeVarMap( decl->base );
     2473        return scrubAllTypeVars( decl );
    26052474}
    26062475
     
    26082477template<typename node_t>
    26092478node_t const * stripGenericMembers( node_t const * decl ) {
    2610         if ( !decl->params.empty() ) {
    2611                 auto mutDecl = ast::mutate( decl );
    2612                 mutDecl->members.clear();
    2613                 return mutDecl;
    2614         }
    2615         return decl;
     2479        if ( decl->params.empty() ) return decl;
     2480        auto mutDecl = ast::mutate( decl );
     2481        mutDecl->members.clear();
     2482        return mutDecl;
    26162483}
    26172484
     
    26292496
    26302497void Eraser::previsit( ast::PointerType const * type ) {
    2631         GuardScope( scopeTypeVars );
    2632         makeTypeVarMap( type, scopeTypeVars );
     2498        guardTypeVarMap( type );
    26332499}
    26342500
    26352501void Eraser::previsit( ast::FunctionType const * type ) {
    2636         GuardScope( scopeTypeVars );
    2637         makeTypeVarMap( type, scopeTypeVars );
     2502        guardTypeVarMap( type );
    26382503}
    26392504
  • src/GenPoly/InstantiateGeneric.h

    r2261bcc rf45772e  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InstantiateGeneric.h --
     7// InstantiateGeneric.h -- Create concrete instances of generic types.
    88//
    99// Author           : Aaron B. Moss
     
    2424
    2525namespace GenPoly {
    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.
     26
    3027void instantiateGeneric( std::list< Declaration* > &translationUnit );
    3128void 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
    3234} // namespace GenPoly
    3335
  • src/GenPoly/InstantiateGenericNew.cpp

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

    r2261bcc rf45772e  
    2020namespace Validate {
    2121
    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
     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
    2429// called by the Pass template (lookupId and addId).
    2530class NoIdSymbolTable {
    2631        ast::SymbolTable base;
    2732public:
     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
    2837#       define FORWARD_X( func, types_and_names, just_names ) \
    2938        inline auto func types_and_names -> decltype( base.func just_names ) { \
  • src/main.cc

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

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

    r2261bcc rf45772e  
     10123456 x
     201234567 x
     3012345678 x
     40123456789 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
     22x
     23...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567
     24x
     25...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678
     26x
     27...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789
     28x
     29...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456@x@
     30...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...01234567@x@
     31...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...012345678@x@
     32...:...:...:...|...:...:...:...|...:...:...:...|...:...:...:...#...:...:...:...|...:...:...:...|...:...:...:...|...:...0123456789@x@
    133abc
    2 abc
     34cccccb
    335xx
    436abcxxx
    537abcyyy
    638aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
     39uuuuuccccuuuuu
    740abc
    8 abc
     41cccccb
    942xx
    1043abcxxx
    1144abcyyy
    1245aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
     46uuuuuccccuuuuu
  • tests/collections/string-istream-manip.cfa

    r2261bcc rf45772e  
    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.
     12static _Istream_Sstr plainjane( string     & s )  { return (_Istream_Sstr)@{  s, {{0p}, -1, {.flags.rwd : false}} }; }
     13static _Istream_Rstr plainjane( string_res & s )  { return (_Istream_Rstr)@{ &s, {{0p}, -1, {.flags.rwd : false}} }; }
     14
     15static 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}
    523
    624int 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
    7140    /* Keep harmonized with io/manipulatorsInput */
    8141    {
     
    23156        sin | ignore( incl( "abc", wdi( 8, s ) ) );     sout | "12" | s;
    24157        sin | ignore( excl( "abc", wdi( 8, s ) ) );     sout | "13" | s;
    25     }
     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.
    26167    {
    27168        string_res s = "yyyyyyyyyyyyyyyyyyyy";
     
    41182        sin | ignore( incl( "abc", wdi( 8, s ) ) );     sout | "12" | s;
    42183        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";
    43191    }
    44192}
  • tests/errors/.expect/scope.txt

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

    r2261bcc rf45772e  
    1 int thisIsAnError;
    2 int thisIsAnError;
     1// Keep harmonized with errors/scope.
    32
    4 int thisIsNotAnError;
    5 float thisIsNotAnError;
     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
    610
    7 int thisIsAlsoNotAnError() {
    8   int thisIsNotAnError;
    9 }
    1011
    11 int thisIsAlsoNotAnError( double x ) {
    12 }
     12        int thisIsAnError;
     13EXPREJ( int thisIsAnError; )
    1314
    14 double thisIsStillNotAnError( double );
    15 double thisIsStillNotAnError( double );
     15        int thisIsNotAnError;
     16        float thisIsNotAnError;
    1617
    17 double butThisIsAnError( double ) {
    18 }
     18        int thisIsAlsoNotAnError() {
     19          int thisIsNotAnError;
     20        }
    1921
    20 double butThisIsAnError( double ) {
    21 }
     22        int thisIsAlsoNotAnError( double x ) {
     23        }
     24
     25        double thisIsStillNotAnError( double );
     26        double thisIsStillNotAnError( double );
     27
     28        double butThisIsAnError( double ) {
     29        }
     30EXPREJ(
     31        double butThisIsAnError( double ) {
     32        }
     33)
    2234
    2335// Local Variables: //
  • tests/io/.expect/manipulatorsInput.arm64.txt

    r2261bcc rf45772e  
    11pre1 "123456", canary ok
    2 pre2a "1234567", exception occurred, canary ok
    3 pre2b "89", canary ok
     2pre2 "1234567", canary ok
     3pre3a "1234567", exception occurred, canary ok
     4pre3b "8", canary ok
     5pre4a "1234567", exception occurred, canary ok
     6pre4b "89", canary ok
    471 yyyyyyyyyyyyyyyyyyyy
    582 abcxxx
     
    151812 wwwwwwww
    161913 wwwwwwww
     2014 rc=1, cccc
     2115 rc=0, q
    17221 yyyyyyyyyyyyyyyyyyyy
    18232 abcxxx
     
    283312 wwwwwwww
    293413 wwwwwwww
     3514 cccc
     3615
    3037a
    3138a
  • tests/io/.expect/manipulatorsInput.x64.txt

    r2261bcc rf45772e  
    11pre1 "123456", canary ok
    2 pre2a "1234567", exception occurred, canary ok
    3 pre2b "89", canary ok
     2pre2 "1234567", canary ok
     3pre3a "1234567", exception occurred, canary ok
     4pre3b "8", canary ok
     5pre4a "1234567", exception occurred, canary ok
     6pre4b "89", canary ok
    471 yyyyyyyyyyyyyyyyyyyy
    582 abcxxx
     
    151812 wwwwwwww
    161913 wwwwwwww
     2014 rc=1, cccc
     2115 rc=0, q
    17221 yyyyyyyyyyyyyyyyyyyy
    18232 abcxxx
     
    283312 wwwwwwww
    293413 wwwwwwww
     3514 cccc
     3615
    3037a
    3138a
  • tests/io/.expect/manipulatorsInput.x86.txt

    r2261bcc rf45772e  
    11pre1 "123456", canary ok
    2 pre2a "1234567", exception occurred, canary ok
    3 pre2b "89", canary ok
     2pre2 "1234567", canary ok
     3pre3a "1234567", exception occurred, canary ok
     4pre3b "8", canary ok
     5pre4a "1234567", exception occurred, canary ok
     6pre4b "89", canary ok
    471 yyyyyyyyyyyyyyyyyyyy
    582 abcxxx
     
    151812 wwwwwwww
    161913 wwwwwwww
     2014 rc=1, cccc
     2115 rc=0, q
    17221 yyyyyyyyyyyyyyyyyyyy
    18232 abcxxx
     
    283312 wwwwwwww
    293413 wwwwwwww
     3514 cccc
     3615
    3037a
    3138a
  • tests/io/.in/manipulatorsInput.txt

    r2261bcc rf45772e  
    11123456
     21234567
     312345678
    24123456789
    35abc
    4 abc
     6cccccb
    57xx
    68abcxxx
    79abcyyy
    810aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
     11uuuuuccccuuuuu
    912abc
    10 abc
     13cccccb
    1114xx
    1215abcxxx
    1316abcyyy
    1417aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww
     18uuuuuccccuuuuu
    1519ab
    16200xff 017 15-15
  • tests/io/manipulatorsInput.cfa

    r2261bcc rf45772e  
    4545                }
    4646
    47                 rep("pre1");
    48                 rep("pre2a");
    49                 rep("pre2b");
     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
    5054                scanf("\n");  // next test does not start with %s so does not tolerate leading whitespace
    5155        }
    5256        {
    5357                char s[] = "yyyyyyyyyyyyyyyyyyyy";
    54                 const char sk[] = "abc";
    55                 scanf( "abc " ); scanf( sk ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s );
     58                const char sk_fmt[] = "%*[abc]";
     59                scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s );
    5660                scanf( "%s", s );                                                               printf( "2 %s\n", s );
    5761                scanf( "%*s" );                                                                 printf( "3 %s\n", s );
     
    6771                scanf( "%*8[abc]" );                                                    printf( "12 %s\n", s );
    6872                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");
    6981        }
    7082        {
     
    8597                sin | ignore( incl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "12" | s;
    8698                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";
    87106        }
    88107    /* Keep harmonized with collections/string-istream-manip */
  • tests/test.py

    r2261bcc rf45772e  
    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=180)
     118        parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=240)
    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

    r2261bcc rf45772e  
    6767                "x86_64"     ) cannon_arch_name="x64";;
    6868                "aarch64"    ) cannon_arch_name="arm64";;
    69                 "arm4"       ) cannon_arch_name="arm64";;
     69                "arm64"      ) 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.