Changeset 28f3a19 for src


Ignore:
Timestamp:
Jun 27, 2018, 3:28:41 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
b21c77a
Parents:
0182bfa (diff), 63238a4 (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' into with_gc

Location:
src
Files:
11 added
4 deleted
98 edited
3 moved

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r0182bfa r28f3a19  
    133133                output << "__attribute__ ((";
    134134                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
    135                         output << (*attr)->get_name();
    136                         if ( ! (*attr)->get_parameters().empty() ) {
     135                        output << (*attr)->name;
     136                        if ( ! (*attr)->parameters.empty() ) {
    137137                                output << "(";
    138                                 genCommaList( (*attr)->get_parameters().begin(), (*attr)->get_parameters().end() );
     138                                genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() );
    139139                                output << ")";
    140140                        } // if
     
    172172        // *** Declarations
    173173        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
     174                // deleted decls should never be used, so don't print them
     175                if ( functionDecl->isDeleted && genC ) return;
    174176                extension( functionDecl );
    175177                genAttributes( functionDecl->get_attributes() );
     
    185187                        functionDecl->get_statements()->accept( *visitor );
    186188                } // if
     189                if ( functionDecl->isDeleted ) {
     190                        output << " = void";
     191                }
    187192        }
    188193
    189194        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
     195                // deleted decls should never be used, so don't print them
     196                if ( objectDecl->isDeleted && genC ) return;
    190197                if (objectDecl->get_name().empty() && genC ) {
    191198                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
     
    206213                        objectDecl->get_init()->accept( *visitor );
    207214                } // if
     215                if ( objectDecl->isDeleted ) {
     216                        output << " = void";
     217                }
    208218
    209219                if ( objectDecl->get_bitfieldWidth() ) {
     
    827837                expr->expr->accept( *visitor );
    828838        }
     839
     840        void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
     841                assertf( ! genC, "Default argument expressions should not reach code generation." );
     842                arg->expr->accept( *visitor );
     843        }
     844
     845        void CodeGenerator::postvisit( GenericExpr * expr ) {
     846                assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     847                output << "_Generic(";
     848                expr->control->accept( *visitor );
     849                output << ", ";
     850                unsigned int numAssocs = expr->associations.size();
     851                unsigned int i = 0;
     852                for ( GenericExpr::Association & assoc : expr->associations ) {
     853                        if (assoc.isDefault) {
     854                                output << "default: ";
     855                        } else {
     856                                output << genType( assoc.type, "", pretty, genC ) << ": ";
     857                        }
     858                        assoc.expr->accept( *visitor );
     859                        if ( i+1 != numAssocs ) {
     860                                output << ", ";
     861                        }
     862                        i++;
     863                }
     864                output << ")";
     865        }
     866
    829867
    830868        // *** Statements
  • src/CodeGen/CodeGenerator.h

    r0182bfa r28f3a19  
    9494                void postvisit( ConstructorExpr * );
    9595                void postvisit( DeletedExpr * );
     96                void postvisit( DefaultArgExpr * );
     97                void postvisit( GenericExpr * );
    9698
    9799                //*** Statements
  • src/Common/Debug.h

    r0182bfa r28f3a19  
    2828namespace Debug {
    2929        /// debug codegen a translation unit
    30         static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {
     30        static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Builtin ) {
    3131        #ifdef DEBUG
    3232                std::list< Declaration * > decls;
  • src/Common/PassVisitor.h

    r0182bfa r28f3a19  
    125125        virtual void visit( InitExpr *  initExpr ) override final;
    126126        virtual void visit( DeletedExpr *  delExpr ) override final;
     127        virtual void visit( DefaultArgExpr * argExpr ) override final;
     128        virtual void visit( GenericExpr * genExpr ) override final;
    127129
    128130        virtual void visit( VoidType * basicType ) override final;
     
    225227        virtual Expression * mutate( InitExpr *  initExpr ) override final;
    226228        virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
     229        virtual Expression * mutate( DefaultArgExpr * argExpr ) override final;
     230        virtual Expression * mutate( GenericExpr * genExpr ) override final;
    227231
    228232        virtual Type * mutate( VoidType * basicType ) override final;
     
    258262
    259263private:
     264        bool inFunction = false;
     265
    260266        template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
    261267        template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
     
    313319        void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    314320        void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
    315         void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith     ( pass, 0, exprs, withStmt ); }
     321        void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
    316322
    317323
  • src/Common/PassVisitor.impl.h

    r0182bfa r28f3a19  
    404404                        indexerAddId( func );
    405405                        maybeAccept_impl( node->type, *this );
     406                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     407                        // a new scope if inFunction is true
     408                        ValueGuard< bool > oldInFunction( inFunction );
     409                        inFunction = true;
    406410                        maybeAccept_impl( node->statements, *this );
    407411                        maybeAccept_impl( node->attributes, *this );
     
    434438                        indexerAddId( func );
    435439                        maybeMutate_impl( node->type, *this );
     440                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     441                        // a new scope if inFunction is true
     442                        ValueGuard< bool > oldInFunction( inFunction );
     443                        inFunction = true;
    436444                        maybeMutate_impl( node->statements, *this );
    437445                        maybeMutate_impl( node->attributes, *this );
     
    712720        VISIT_START( node );
    713721        {
    714                 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     722                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     723                ValueGuard< bool > oldInFunction( inFunction );
     724                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    715725                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     726                inFunction = false;
    716727                visitStatementList( node->kids );
    717728        }
     
    723734        MUTATE_START( node );
    724735        {
    725                 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     736                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     737                ValueGuard< bool > oldInFunction( inFunction );
     738                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    726739                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     740                inFunction = false;
    727741                mutateStatementList( node->kids );
    728742        }
     
    828842        VISIT_START( node );
    829843
    830         visitExpression( node->condition );
    831         node->body = visitStatement( node->body );
     844        {
     845                // while statements introduce a level of scope (for the initialization)
     846                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     847                maybeAccept_impl( node->initialization, *this );
     848                visitExpression ( node->condition );
     849                node->body = visitStatement( node->body );
     850        }
    832851
    833852        VISIT_END( node );
     
    838857        MUTATE_START( node );
    839858
    840         node->condition = mutateExpression( node->condition );
    841         node->body      = mutateStatement ( node->body      );
     859        {
     860                // while statements introduce a level of scope (for the initialization)
     861                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     862                maybeMutate_impl( node->initialization, *this );
     863                node->condition = mutateExpression( node->condition );
     864                node->body      = mutateStatement ( node->body      );
     865        }
     866
    842867
    843868        MUTATE_END( Statement, node );
     
    20742099
    20752100//--------------------------------------------------------------------------
     2101// DefaultArgExpr
     2102template< typename pass_type >
     2103void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
     2104        VISIT_START( node );
     2105
     2106        indexerScopedAccept( node->result, *this );
     2107        maybeAccept_impl( node->expr, *this );
     2108
     2109        VISIT_END( node );
     2110}
     2111
     2112template< typename pass_type >
     2113Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
     2114        MUTATE_START( node );
     2115
     2116        indexerScopedMutate( node->env, *this );
     2117        indexerScopedMutate( node->result, *this );
     2118        maybeMutate_impl( node->expr, *this );
     2119
     2120        MUTATE_END( Expression, node );
     2121}
     2122
     2123//--------------------------------------------------------------------------
     2124// GenericExpr
     2125template< typename pass_type >
     2126void PassVisitor< pass_type >::visit( GenericExpr * node ) {
     2127        VISIT_START( node );
     2128
     2129        indexerScopedAccept( node->result, *this );
     2130        maybeAccept_impl( node->control, *this );
     2131        for ( GenericExpr::Association & assoc : node->associations ) {
     2132                indexerScopedAccept( assoc.type, *this );
     2133                maybeAccept_impl( assoc.expr, *this );
     2134        }
     2135
     2136        VISIT_END( node );
     2137}
     2138
     2139template< typename pass_type >
     2140Expression * PassVisitor< pass_type >::mutate( GenericExpr * node ) {
     2141        MUTATE_START( node );
     2142
     2143        indexerScopedMutate( node->env, *this );
     2144        indexerScopedMutate( node->result, *this );
     2145        maybeMutate_impl( node->control, *this );
     2146        for ( GenericExpr::Association & assoc : node->associations ) {
     2147                indexerScopedMutate( assoc.type, *this );
     2148                maybeMutate_impl( assoc.expr, *this );
     2149        }
     2150
     2151        MUTATE_END( Expression, node );
     2152}
     2153
     2154//--------------------------------------------------------------------------
    20762155// VoidType
    20772156template< typename pass_type >
  • src/Common/SemanticError.cc

    r0182bfa r28f3a19  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 16 15:01:20 2018
    13 // Update Count     : 9
     12// Last Modified On : Thu Jun  7 08:05:26 2018
     13// Update Count     : 10
    1414//
    1515
     
    9797void SemanticError( CodeLocation location, std::string error ) {
    9898        SemanticErrorThrow = true;
    99         throw SemanticErrorException(location, error);
     99        throw SemanticErrorException( location, error );
    100100}
    101101
  • src/Concurrency/Keywords.cc

    r0182bfa r28f3a19  
    192192                void postvisit(   StructDecl * decl );
    193193
    194                 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     194                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
    195195                void validate( DeclarationWithType * );
    196196                void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
     
    431431        void MutexKeyword::postvisit(FunctionDecl* decl) {
    432432
    433                 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
    434                 if( mutexArgs.empty() ) return;
    435 
    436                 if( CodeGen::isConstructor(decl->name) ) SemanticError( decl, "constructors cannot have mutex parameters" );
    437 
     433                bool first = false;
     434                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first );
    438435                bool isDtor = CodeGen::isDestructor( decl->name );
    439436
     437                // Is this function relevant to monitors
     438                if( mutexArgs.empty() ) {
     439                        // If this is the destructor for a monitor it must be mutex
     440                        if(isDtor) {
     441                                Type* ty = decl->get_functionType()->get_parameters().front()->get_type();
     442
     443                                // If it's a copy, it's not a mutex
     444                                ReferenceType* rty = dynamic_cast< ReferenceType * >( ty );
     445                                if( ! rty ) return;
     446
     447                                // If we are not pointing directly to a type, it's not a mutex
     448                                Type* base = rty->get_base();
     449                                if( dynamic_cast< ReferenceType * >( base ) ) return;
     450                                if( dynamic_cast< PointerType * >( base ) ) return;
     451
     452                                // Check if its a struct
     453                                StructInstType * baseStruct = dynamic_cast< StructInstType * >( base );
     454                                if( !baseStruct ) return;
     455
     456                                // Check if its a monitor
     457                                if(baseStruct->baseStruct->is_monitor() || baseStruct->baseStruct->is_thread())
     458                                        SemanticError( decl, "destructors for structures declared as \"monitor\" must use mutex parameters\n" );
     459                        }
     460                        return;
     461                }
     462
     463                // Monitors can't be constructed with mutual exclusion
     464                if( CodeGen::isConstructor(decl->name) && !first ) SemanticError( decl, "constructors cannot have mutex parameters" );
     465
     466                // It makes no sense to have multiple mutex parameters for the destructor
    440467                if( isDtor && mutexArgs.size() != 1 ) SemanticError( decl, "destructors can only have 1 mutex argument" );
    441468
     469                // Make sure all the mutex arguments are monitors
    442470                for(auto arg : mutexArgs) {
    443471                        validate( arg );
    444472                }
    445473
     474                // Check if we need to instrument the body
    446475                CompoundStmt* body = decl->get_statements();
    447476                if( ! body ) return;
    448477
     478                // Do we have the required headers
    449479                if( !monitor_decl || !guard_decl || !dtor_guard_decl )
    450                         SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>" );
    451 
     480                        SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>\n" );
     481
     482                // Instrument the body
    452483                if( isDtor ) {
    453484                        addDtorStatments( decl, body, mutexArgs );
     
    474505        }
    475506
    476         std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
     507        std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl, bool & first ) {
    477508                std::list<DeclarationWithType*> mutexArgs;
    478509
     510                bool once = true;
    479511                for( auto arg : decl->get_functionType()->get_parameters()) {
    480512                        //Find mutex arguments
    481513                        Type* ty = arg->get_type();
    482514                        if( ! ty->get_mutex() ) continue;
     515
     516                        if(once) {first = true;}
     517                        once = false;
    483518
    484519                        //Append it to the list
  • src/ControlStruct/ForExprMutator.cc

    r0182bfa r28f3a19  
    4545                return hoist( forStmt, forStmt->initialization );
    4646        }
     47        Statement *ForExprMutator::postmutate( WhileStmt *whileStmt ) {
     48                return hoist( whileStmt, whileStmt->initialization );
     49        }
    4750} // namespace ControlStruct
    4851
  • src/ControlStruct/ForExprMutator.h

    r0182bfa r28f3a19  
    1818class IfStmt;
    1919class ForStmt;
     20class WhileStmt;
    2021class Statement;
    2122
     
    2526                Statement *postmutate( IfStmt * );
    2627                Statement *postmutate( ForStmt * );
     28                Statement *postmutate( WhileStmt * );
    2729        };
    2830} // namespace ControlStruct
  • src/ControlStruct/Mutate.cc

    r0182bfa r28f3a19  
    2727#include "SynTree/Visitor.h"       // for acceptAll
    2828
    29 using namespace std;
     29namespace ControlStruct {
     30        void fixLabels( std::list< Declaration * > & translationUnit ) {
     31                PassVisitor<LabelFixer> lfix;
     32                acceptAll( translationUnit, lfix );
     33        }
    3034
    31 namespace ControlStruct {
    32         void mutate( std::list< Declaration * > translationUnit ) {
    33                 // hoist initialization out of for statements
     35        void hoistControlDecls( std::list< Declaration * > & translationUnit ) {
    3436                PassVisitor<ForExprMutator> formut;
    35 
    36                 // normalizes label definitions and generates multi-level exit labels
    37                 PassVisitor<LabelFixer> lfix;
    38 
    3937                mutateAll( translationUnit, formut );
    40                 acceptAll( translationUnit, lfix );
    4138        }
    4239} // namespace CodeGen
  • src/ControlStruct/Mutate.h

    r0182bfa r28f3a19  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Mutate.h -- 
     7// Mutate.h --
    88//
    99// Author           : Rodolfo G. Esteves
     
    2020class Declaration;
    2121
     22/// Desugars Cforall control structures
    2223namespace ControlStruct {
    23         /// Desugars Cforall control structures
    24         void mutate( std::list< Declaration* > translationUnit );
     24        /// normalizes label definitions and generates multi-level exit labels
     25        void fixLabels( std::list< Declaration * > & translationUnit );
     26
     27        /// hoist initialization out of for statements
     28        void hoistControlDecls( std::list< Declaration * > & translationUnit );
    2529} // namespace ControlStruct
    2630
  • src/GenPoly/Lvalue.cc

    r0182bfa r28f3a19  
    145145
    146146        namespace {
    147                 // true for intrinsic function calls that return a reference
     147                // true for intrinsic function calls that return an lvalue in C
    148148                bool isIntrinsicReference( Expression * expr ) {
     149                        // known intrinsic-reference prelude functions
     150                        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
    149151                        if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) {
    150152                                std::string fname = InitTweak::getFunctionName( untyped );
    151                                 // known intrinsic-reference prelude functions
    152                                 return fname == "*?" || fname == "?[?]";
     153                                return lvalueFunctions.count(fname);
    153154                        } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
    154155                                if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) {
    155                                         // use type of return variable rather than expr result type, since it may have been changed to a pointer type
    156                                         FunctionType * ftype = GenPoly::getFunctionType( func->get_type() );
    157                                         Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type();
    158                                         return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret );
     156                                        return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
    159157                                }
    160158                        }
     
    210208                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
    211209
    212                                                 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
     210                                                if ( function->linkage != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    213211                                                        // needed for definition of prelude functions, etc.
    214212                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
     
    226224                                                        arg = new AddressExpr( arg );
    227225                                                // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    228                                                 } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
     226                                                } else if ( function->linkage == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    229227                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
    230228                                                        PRINT(
  • src/Parser/DeclarationNode.cc

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 22 08:39:29 2018
    13 // Update Count     : 1074
     12// Last Modified On : Thu Jun  7 12:08:55 2018
     13// Update Count     : 1079
    1414//
    1515
     
    173173}
    174174
    175 DeclarationNode * DeclarationNode::newFunction( string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {
     175DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {
    176176        DeclarationNode * newnode = new DeclarationNode;
    177177        newnode->name = name;
     
    244244} // DeclarationNode::newForall
    245245
    246 DeclarationNode * DeclarationNode::newFromTypedef( string * name ) {
     246DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {
    247247        DeclarationNode * newnode = new DeclarationNode;
    248248        newnode->type = new TypeData( TypeData::SymbolicInst );
     
    267267} // DeclarationNode::newAggregate
    268268
    269 DeclarationNode * DeclarationNode::newEnum( string * name, DeclarationNode * constants, bool body ) {
     269DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) {
    270270        assert( name );
    271271        DeclarationNode * newnode = new DeclarationNode;
     
    277277} // DeclarationNode::newEnum
    278278
    279 DeclarationNode * DeclarationNode::newEnumConstant( string * name, ExpressionNode * constant ) {
     279DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) {
    280280        DeclarationNode * newnode = new DeclarationNode;
    281281        newnode->name = name;
     
    284284} // DeclarationNode::newEnumConstant
    285285
    286 DeclarationNode * DeclarationNode::newName( string * name ) {
     286DeclarationNode * DeclarationNode::newName( const string * name ) {
    287287        DeclarationNode * newnode = new DeclarationNode;
    288288        newnode->name = name;
     
    290290} // DeclarationNode::newName
    291291
    292 DeclarationNode * DeclarationNode::newFromTypeGen( string * name, ExpressionNode * params ) {
     292DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) {
    293293        DeclarationNode * newnode = new DeclarationNode;
    294294        newnode->type = new TypeData( TypeData::SymbolicInst );
     
    299299} // DeclarationNode::newFromTypeGen
    300300
    301 DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, string * name ) {
     301DeclarationNode * DeclarationNode::newTypeParam( TypeClass tc, const string * name ) {
    302302        DeclarationNode * newnode = new DeclarationNode;
    303303        newnode->type = nullptr;
     
    330330} // DeclarationNode::newTraitUse
    331331
    332 DeclarationNode * DeclarationNode::newTypeDecl( string * name, DeclarationNode * typeParams ) {
     332DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) {
    333333        DeclarationNode * newnode = new DeclarationNode;
    334334        newnode->name = name;
     
    405405} // DeclarationNode::newBuiltinType
    406406
    407 DeclarationNode * DeclarationNode::newAttr( string * name, ExpressionNode * expr ) {
     407DeclarationNode * DeclarationNode::newAttr( const string * name, ExpressionNode * expr ) {
    408408        DeclarationNode * newnode = new DeclarationNode;
    409409        newnode->type = nullptr;
     
    414414}
    415415
    416 DeclarationNode * DeclarationNode::newAttr( string * name, DeclarationNode * type ) {
     416DeclarationNode * DeclarationNode::newAttr( const string * name, DeclarationNode * type ) {
    417417        DeclarationNode * newnode = new DeclarationNode;
    418418        newnode->type = nullptr;
     
    423423}
    424424
    425 DeclarationNode * DeclarationNode::newAttribute( string * name, ExpressionNode * expr ) {
     425DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
    426426        DeclarationNode * newnode = new DeclarationNode;
    427427        newnode->type = nullptr;
     
    544544                                        type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier
    545545                                } else {                                                                // not polymorphic
    546                                         type->aggregate.params = q->type->forall; // make polymorphic type
    547                                         // change implicit typedef from TYPEDEFname to TYPEGENname
    548                                         typedefTable.changeKind( *type->aggregate.name, TYPEGENname );
     546                                        type->aggregate.params = q->type->forall; // set forall qualifier
    549547                                } // if
    550548                        } else {                                                                        // not polymorphic
     
    10651063                        SemanticError( this, "invalid function specifier for " );
    10661064                } // if
    1067                 return buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     1065                bool isDelete = initializer && initializer->get_isDelete();
     1066                Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     1067                if ( isDelete ) {
     1068                        DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
     1069                        dwt->isDeleted = true;
     1070                }
     1071                return decl;
    10681072        } // if
    10691073
  • src/Parser/ExpressionNode.cc

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 22 11:57:39 2018
    13 // Update Count     : 801
     12// Last Modified On : Mon Jun  4 21:24:45 2018
     13// Update Count     : 802
    1414//
    1515
     
    314314
    315315Expression * build_constantStr( string & str ) {
     316        assert( str.length() > 0 );
    316317        string units;                                                                           // units
    317318        sepString( str, units, '"' );                                           // separate constant from units
  • src/Parser/InitializerNode.cc

    r0182bfa r28f3a19  
    2727
    2828InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des )
    29                 : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {
     29                : expr( _expr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) {
    3030        if ( aggrp )
    3131                kids = dynamic_cast< InitializerNode * >( get_next() );
     
    3636
    3737InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des )
    38                 : expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ) {
     38                : expr( nullptr ), aggregate( aggrp ), designator( des ), kids( nullptr ), maybeConstructed( true ), isDelete( false ) {
    3939        if ( init )
    4040                set_last( init );
     
    4646                set_next( nullptr );
    4747} // InitializerNode::InitializerNode
     48
     49InitializerNode::InitializerNode( bool isDelete ) : expr( nullptr ), aggregate( false ), designator( nullptr ), kids( nullptr ), maybeConstructed( false ), isDelete( isDelete ) {}
    4850
    4951InitializerNode::~InitializerNode() {
     
    8486
    8587Initializer * InitializerNode::build() const {
     88        assertf( ! isDelete, "Should not build delete stmt InitializerNode" );
    8689        if ( aggregate ) {
    8790                // steal designators from children
  • src/Parser/ParseNode.h

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 30 09:19:17 2018
    13 // Update Count     : 831
     12// Last Modified On : Wed Jun  6 16:17:18 2018
     13// Update Count     : 843
    1414//
    1515
     
    7777
    7878        ParseNode * next = nullptr;
    79         std::string * name = nullptr;
     79        const std::string * name = nullptr;
    8080        CodeLocation location = yylloc;
    8181}; // ParseNode
     
    8787        InitializerNode( ExpressionNode *, bool aggrp = false,  ExpressionNode * des = nullptr );
    8888        InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
     89        InitializerNode( bool isDelete );
    8990        ~InitializerNode();
    9091        virtual InitializerNode * clone() const { assert( false ); return nullptr; }
     
    9798        InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
    9899        bool get_maybeConstructed() const { return maybeConstructed; }
     100
     101        bool get_isDelete() const { return isDelete; }
    99102
    100103        InitializerNode * next_init() const { return kids; }
     
    110113        InitializerNode * kids;
    111114        bool maybeConstructed;
     115        bool isDelete;
    112116}; // InitializerNode
    113117
     
    167171};
    168172
    169 Expression * build_constantInteger( std::string &str );
    170 Expression * build_constantFloat( std::string &str );
    171 Expression * build_constantChar( std::string &str );
    172 Expression * build_constantStr( std::string &str );
     173Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
     174Expression * build_constantFloat( std::string & str );
     175Expression * build_constantChar( std::string & str );
     176Expression * build_constantStr( std::string & str );
    173177Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
    174178Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
     
    226230        static DeclarationNode * newBuiltinType( BuiltinType );
    227231        static DeclarationNode * newForall( DeclarationNode * );
    228         static DeclarationNode * newFromTypedef( std::string * );
    229         static DeclarationNode * newFunction( std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
     232        static DeclarationNode * newFromTypedef( const std::string * );
     233        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    230234        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    231         static DeclarationNode * newEnum( std::string * name, DeclarationNode * constants, bool body );
    232         static DeclarationNode * newEnumConstant( std::string * name, ExpressionNode * constant );
    233         static DeclarationNode * newName( std::string * );
    234         static DeclarationNode * newFromTypeGen( std::string *, ExpressionNode * params );
    235         static DeclarationNode * newTypeParam( TypeClass, std::string * );
     235        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body );
     236        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
     237        static DeclarationNode * newName( const std::string * );
     238        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
     239        static DeclarationNode * newTypeParam( TypeClass, const std::string * );
    236240        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
    237241        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
    238         static DeclarationNode * newTypeDecl( std::string * name, DeclarationNode * typeParams );
     242        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
    239243        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
    240244        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
     
    243247        static DeclarationNode * newTuple( DeclarationNode * members );
    244248        static DeclarationNode * newTypeof( ExpressionNode * expr );
    245         static DeclarationNode * newAttr( std::string *, ExpressionNode * expr ); // @ attributes
    246         static DeclarationNode * newAttr( std::string *, DeclarationNode * type ); // @ attributes
    247         static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
     249        static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
     250        static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
     251        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
    248252        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    249253        static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
     
    399403};
    400404
     405Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
    401406Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
    402407Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
    403408Statement * build_case( ExpressionNode * ctl );
    404409Statement * build_default();
    405 Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind = false );
     410Statement * build_while( IfCtl * ctl, StatementNode * stmt );
     411Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
    406412Statement * build_for( ForCtl * forctl, StatementNode * stmt );
    407413Statement * build_branch( BranchStmt::Type kind );
  • src/Parser/StatementNode.cc

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr 30 09:21:16 2018
    13 // Update Count     : 354
     12// Last Modified On : Tue Jun  5 08:58:34 2018
     13// Update Count     : 362
    1414//
    1515
     
    6969        caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
    7070        return this;
    71 }
     71} // StatementNode::append_last_case
    7272
    7373Statement * build_expr( ExpressionNode * ctl ) {
    7474        Expression * e = maybeMoveBuild< Expression >( ctl );
    7575
    76         if ( e )
    77                 return new ExprStmt( e );
    78         else
    79                 return new NullStmt();
    80 }
    81 
    82 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
    83         Statement * thenb, * elseb = 0;
    84         std::list< Statement * > branches;
    85         buildMoveList< Statement, StatementNode >( then_stmt, branches );
    86         assert( branches.size() == 1 );
    87         thenb = branches.front();
    88 
    89         if ( else_stmt ) {
    90                 std::list< Statement * > branches;
    91                 buildMoveList< Statement, StatementNode >( else_stmt, branches );
    92                 assert( branches.size() == 1 );
    93                 elseb = branches.front();
    94         } // if
    95 
    96         std::list< Statement * > init;
     76        if ( e ) return new ExprStmt( e );
     77        else return new NullStmt();
     78} // build_expr
     79
     80Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init ) {
    9781        if ( ctl->init != 0 ) {
    9882                buildMoveList( ctl->init, init );
     
    10286        if ( ctl->condition ) {
    10387                // compare the provided condition against 0
    104                 cond =  notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
     88                cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
    10589        } else {
    10690                for ( Statement * stmt : init ) {
     
    11397        }
    11498        delete ctl;
     99        return cond;
     100} // build_if_control
     101
     102Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
     103        Statement * thenb, * elseb = nullptr;
     104        std::list< Statement * > branches;
     105        buildMoveList< Statement, StatementNode >( then_stmt, branches );
     106        assert( branches.size() == 1 );
     107        thenb = branches.front();
     108
     109        if ( else_stmt ) {
     110                std::list< Statement * > branches;
     111                buildMoveList< Statement, StatementNode >( else_stmt, branches );
     112                assert( branches.size() == 1 );
     113                elseb = branches.front();
     114        } // if
     115
     116        std::list< Statement * > init;
     117        Expression * cond = build_if_control( ctl, init );
    115118        return new IfStmt( cond, thenb, elseb, init );
    116 }
     119} // build_if
    117120
    118121Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
     
    130133        // branches.size() == 0 for switch (...) {}, i.e., no declaration or statements
    131134        return new SwitchStmt( maybeMoveBuild< Expression >(ctl), branches );
    132 }
     135} // build_switch
     136
    133137Statement * build_case( ExpressionNode * ctl ) {
    134138        std::list< Statement * > branches;
    135139        return new CaseStmt( maybeMoveBuild< Expression >(ctl), branches );
    136 }
     140} // build_case
     141
    137142Statement * build_default() {
    138143        std::list< Statement * > branches;
    139144        return new CaseStmt( nullptr, branches, true );
    140 }
    141 
    142 Statement * build_while( ExpressionNode * ctl, StatementNode * stmt, bool kind ) {
    143         std::list< Statement * > branches;
    144         buildMoveList< Statement, StatementNode >( stmt, branches );
    145         assert( branches.size() == 1 );
    146         return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), kind );
    147 }
     145} // build_default
     146
     147Statement * build_while( IfCtl * ctl, StatementNode * stmt ) {
     148        std::list< Statement * > branches;
     149        buildMoveList< Statement, StatementNode >( stmt, branches );
     150        assert( branches.size() == 1 );
     151
     152        std::list< Statement * > init;
     153        Expression * cond = build_if_control( ctl, init );
     154        return new WhileStmt( cond, branches.front(), init, false );
     155} // build_while
     156
     157Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt ) {
     158        std::list< Statement * > branches;
     159        buildMoveList< Statement, StatementNode >( stmt, branches );
     160        assert( branches.size() == 1 );
     161
     162        std::list< Statement * > init;
     163        return new WhileStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), branches.front(), init, true );
     164} // build_do_while
    148165
    149166Statement * build_for( ForCtl * forctl, StatementNode * stmt ) {
     
    167184        delete forctl;
    168185        return new ForStmt( init, cond, incr, branches.front() );
    169 }
     186} // build_for
    170187
    171188Statement * build_branch( BranchStmt::Type kind ) {
    172189        Statement * ret = new BranchStmt( "", kind );
    173190        return ret;
    174 }
     191} // build_branch
     192
    175193Statement * build_branch( std::string * identifier, BranchStmt::Type kind ) {
    176194        Statement * ret = new BranchStmt( * identifier, kind );
    177195        delete identifier;                                                                      // allocated by lexer
    178196        return ret;
    179 }
     197} // build_branch
     198
    180199Statement * build_computedgoto( ExpressionNode * ctl ) {
    181200        return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto );
    182 }
     201} // build_computedgoto
    183202
    184203Statement * build_return( ExpressionNode * ctl ) {
     
    186205        buildMoveList( ctl, exps );
    187206        return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
    188 }
     207} // build_return
    189208
    190209Statement * build_throw( ExpressionNode * ctl ) {
     
    193212        assertf( exps.size() < 2, "This means we are leaking memory");
    194213        return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
    195 }
     214} // build_throw
    196215
    197216Statement * build_resume( ExpressionNode * ctl ) {
     
    200219        assertf( exps.size() < 2, "This means we are leaking memory");
    201220        return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
    202 }
     221} // build_resume
    203222
    204223Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
     
    206225        (void)target;
    207226        assertf( false, "resume at (non-local throw) is not yet supported," );
    208 }
     227} // build_resume_at
    209228
    210229Statement * build_try( StatementNode * try_stmt, StatementNode * catch_stmt, StatementNode * finally_stmt ) {
     
    214233        FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_stmt) );
    215234        return new TryStmt( tryBlock, branches, finallyBlock );
    216 }
     235} // build_try
     236
    217237Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
    218238        std::list< Statement * > branches;
     
    220240        assert( branches.size() == 1 );
    221241        return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), branches.front() );
    222 }
     242} // build_catch
     243
    223244Statement * build_finally( StatementNode * stmt ) {
    224245        std::list< Statement * > branches;
     
    226247        assert( branches.size() == 1 );
    227248        return new FinallyStmt( dynamic_cast< CompoundStmt * >( branches.front() ) );
    228 }
     249} // build_finally
    229250
    230251WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) {
     
    247268
    248269        return node;
    249 }
     270} // build_waitfor
    250271
    251272WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) {
     
    266287
    267288        return node;
    268 }
     289} // build_waitfor
    269290
    270291WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) {
     
    275296                node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    276297                node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    277         }
    278         else {
     298        } else {
    279299                node->orelse.statement  = maybeMoveBuild<Statement >( stmt );
    280300                node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    281         }
     301        } // if
    282302
    283303        return node;
    284 }
     304} // build_waitfor_timeout
    285305
    286306WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when,  StatementNode * else_stmt, ExpressionNode * else_when ) {
     
    295315
    296316        return node;
    297 }
     317} // build_waitfor_timeout
    298318
    299319WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
     
    302322        Statement * s = maybeMoveBuild<Statement>( stmt );
    303323        return new WithStmt( e, s );
    304 }
     324} // build_with
    305325
    306326Statement * build_compound( StatementNode * first ) {
     
    308328        buildMoveList( first, cs->get_kids() );
    309329        return cs;
    310 }
     330} // build_compound
    311331
    312332Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     
    318338        buildMoveList( clobber, clob );
    319339        return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
    320 }
     340} // build_asm
    321341
    322342Statement * build_directive( string * directive ) {
    323343        return new DirectiveStmt( *directive );
    324 }
     344} // build_directive
    325345
    326346// Local Variables: //
  • src/Parser/TypeData.cc

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 26 13:46:07 2018
    13 // Update Count     : 603
     12// Last Modified On : Wed Jun  6 17:40:33 2018
     13// Update Count     : 604
    1414//
    1515
     
    6565          case Aggregate:
    6666                // aggregate = new Aggregate_t;
     67                aggregate.kind = DeclarationNode::NoAggregate;
    6768                aggregate.name = nullptr;
    6869                aggregate.params = nullptr;
     
    7071                aggregate.fields = nullptr;
    7172                aggregate.body = false;
     73                aggregate.tagged = false;
     74                aggregate.parent = nullptr;
    7275                break;
    7376          case AggregateInst:
     
    198201                break;
    199202          case Aggregate:
     203                newtype->aggregate.kind = aggregate.kind;
    200204                newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
    201205                newtype->aggregate.params = maybeClone( aggregate.params );
    202206                newtype->aggregate.actuals = maybeClone( aggregate.actuals );
    203207                newtype->aggregate.fields = maybeClone( aggregate.fields );
    204                 newtype->aggregate.kind = aggregate.kind;
    205208                newtype->aggregate.body = aggregate.body;
    206209                newtype->aggregate.tagged = aggregate.tagged;
     
    575578
    576579          case DeclarationNode::Int128:
    577                 ret = td->signedness == 1 ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
     580                ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
    578581                if ( td->length != DeclarationNode::NoLength ) {
    579582                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     
    599602                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    600603                } // if
    601                 if ( td->basictype == DeclarationNode::Float && td->length == DeclarationNode::Long ) {
     604                if ( td->basictype != DeclarationNode::Double && td->length == DeclarationNode::Long ) {
    602605                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    603606                } // if
     
    605608                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
    606609                } // if
     610
     611                if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
     612                        // if ( td->complextype != DeclarationNode::NoComplexType ) {
     613                        //      genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
     614                        // }
     615                        if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
     616                        else ret = BasicType::Float128;
     617                        break;
     618                }
    607619
    608620                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
  • src/Parser/TypedefTable.cc

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 22 08:40:01 2018
    13 // Update Count     : 121
     12// Last Modified On : Fri Jun 22 06:14:39 2018
     13// Update Count     : 206
    1414//
    1515
     
    1717#include "TypedefTable.h"
    1818#include <cassert>                                                                              // for assert
     19#include <iostream>
    1920
    2021#if 0
    21 #include <iostream>
    22 #define debugPrint( x ) cerr << x
     22#define debugPrint( code ) code
    2323#else
    24 #define debugPrint( x )
     24#define debugPrint( code )
    2525#endif
    2626
    2727using namespace std;                                                                    // string, iostream
    2828
     29debugPrint(
     30static const char *kindName( int kind ) {
     31        switch ( kind ) {
     32          case IDENTIFIER: return "identifier";
     33          case TYPEDEFname: return "typedef";
     34          case TYPEGENname: return "typegen";
     35          default:
     36                cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
     37                abort();
     38        } // switch
     39} // kindName
     40)
     41
    2942TypedefTable::~TypedefTable() {
    3043        if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) {
    31                 // std::cerr << "scope failure " << kindTable.currentScope() << endl;
     44                cerr << "Error: cfa-cpp internal error, scope failure " << kindTable.currentScope() << endl;
     45                abort();
    3246        } // if
    3347} // TypedefTable::~TypedefTable
     
    4458} // TypedefTable::isKind
    4559
    46 void TypedefTable::changeKind( const string & identifier, int kind ) {
    47         KindTable::iterator posn = kindTable.find( identifier );
    48         if ( posn != kindTable.end() ) posn->second = kind;     // exists => update
    49 } // TypedefTable::changeKind
    50 
    5160// SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by
    5261// "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if the
    5362// name is explicitly used.
    54 void TypedefTable::makeTypedef( const string & name ) {
     63void TypedefTable::makeTypedef( const string & name, int kind ) {
     64//    Check for existence is necessary to handle:
     65//        struct Fred {};
     66//        void Fred();
     67//        void fred() {
     68//           struct Fred act; // do not add as type in this scope
     69//           Fred();
     70//        }
    5571        if ( ! typedefTable.exists( name ) ) {
    56                 typedefTable.addToEnclosingScope( name, TYPEDEFname );
     72                typedefTable.addToEnclosingScope( name, kind, "MTD" );
    5773        } // if
    5874} // TypedefTable::makeTypedef
    5975
    60 void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind ) {
    61         assert( kindTable.currentScope() >= 1 );
    62         auto scope = kindTable.currentScope() - 1;
    63         debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << endl );
     76void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
     77        auto scope = kindTable.currentScope();
     78        debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
     79        auto ret = kindTable.insertAt( scope, identifier, kind );
     80        //if ( ! ret.second ) ret.first->second = kind;         // exists => update
     81        assert( ret.first->second == kind );                            // exists
     82} // TypedefTable::addToScope
     83
     84void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
     85        assert( kindTable.currentScope() >= 1 + level );
     86        auto scope = kindTable.currentScope() - 1 - level;
     87        debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << endl );
    6488        auto ret = kindTable.insertAt( scope, identifier, kind );
    6589        if ( ! ret.second ) ret.first->second = kind;           // exists => update
     
    6892void TypedefTable::enterScope() {
    6993        kindTable.beginScope();
    70         debugPrint( "Entering scope " << kindTable.currentScope() << endl );
     94        debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl; print() );
    7195} // TypedefTable::enterScope
    7296
    7397void TypedefTable::leaveScope() {
    74         debugPrint( "Leaving scope " << kindTable.currentScope() << endl );
     98        debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl; print() );
    7599        kindTable.endScope();
    76100} // TypedefTable::leaveScope
    77101
    78 // void TypedefTable::print( void ) const {
    79 //      for ( KindTable::const_iterator i = table.begin(); i != table.end(); i++) {
    80 //              debugPrint( (*i ).first << ": " );
    81 //              list< Entry > declList = (*i).second;
    82 //              for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) {
    83 //                      debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " );
    84 //              }
    85 //              debugPrint( endl );
    86 //      } // for
    87 // }
     102void TypedefTable::print( void ) const {
     103        KindTable::size_type scope = kindTable.currentScope();
     104        debugPrint( cerr << "[" << scope << "]" );
     105        for ( KindTable::const_iterator i = kindTable.begin(); i != kindTable.end(); i++ ) {
     106                while ( i.get_level() != scope ) {
     107                        --scope;
     108                        debugPrint( cerr << endl << "[" << scope << "]" );
     109                } // while
     110                debugPrint( cerr << " " << (*i).first << ":" << kindName( (*i).second ) );
     111        } // for
     112        while ( scope > 0 ) {
     113                --scope;
     114                debugPrint( cerr << endl << "[" << scope << "]" );
     115        } // while
     116        debugPrint( cerr << endl );
     117} // TypedefTable::print
    88118
    89119// Local Variables: //
  • src/Parser/TypedefTable.h

    r0182bfa r28f3a19  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 22 08:39:29 2018
    13 // Update Count     : 77
     12// Last Modified On : Fri Jun 22 05:29:58 2018
     13// Update Count     : 86
    1414//
    1515
     
    2525        typedef ScopedMap< std::string, int > KindTable;
    2626        KindTable kindTable;   
     27        unsigned int level = 0;
    2728  public:
    2829        ~TypedefTable();
     
    3031        bool exists( const std::string & identifier );
    3132        int isKind( const std::string & identifier ) const;
    32         void changeKind( const std::string & identifier, int kind );
    33         void makeTypedef( const std::string & name );
    34         void addToEnclosingScope( const std::string & identifier, int kind );
     33        void makeTypedef( const std::string & name, int kind = TYPEDEFname );
     34        void addToScope( const std::string & identifier, int kind, const char * );
     35        void addToEnclosingScope( const std::string & identifier, int kind, const char * );
    3536
    3637        void enterScope();
    3738        void leaveScope();
     39
     40        void up() { level += 1; }
     41        void down() { level -= 1; }
     42
     43        void print( void ) const;
    3844}; // TypedefTable
    3945
  • src/Parser/lex.ll

    r0182bfa r28f3a19  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu May  3 13:42:40 2018
    13  * Update Count     : 676
     12 * Last Modified On : Wed Jun 20 09:08:28 2018
     13 * Update Count     : 682
    1414 */
    1515
     
    2525//**************************** Includes and Defines ****************************
    2626
     27// trigger before each matching rule's action
     28#define YY_USER_ACTION \
     29        yylloc.first_line = yylineno; \
     30        yylloc.first_column = column; \
     31        column += yyleng; \
     32        yylloc.last_column = column; \
     33        yylloc.last_line = yylineno; \
     34        yylloc.filename = yyfilename ? yyfilename : "";
    2735unsigned int column = 0;                                                                // position of the end of the last token parsed
    28 #define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : "";                          // trigger before each matching rule's action
    2936
    3037#include <string>
     
    4956#define NUMERIC_RETURN(x)       rm_underscore(); RETURN_VAL( x ) // numeric constant
    5057#define KEYWORD_RETURN(x)       RETURN_CHAR( x )                        // keyword
    51 #define QKEYWORD_RETURN(x)      typedefTable.isKind( yytext ); RETURN_VAL(x); // quasi-keyword
     58#define QKEYWORD_RETURN(x)      RETURN_VAL(x);                          // quasi-keyword
    5259#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    5360#define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
     
    232239finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
    233240float                   { KEYWORD_RETURN(FLOAT); }
     241_Float32                { KEYWORD_RETURN(FLOAT); }                              // GCC
     242_Float32x               { KEYWORD_RETURN(FLOAT); }                              // GCC
     243_Float64                { KEYWORD_RETURN(DOUBLE); }                             // GCC
     244_Float64x               { KEYWORD_RETURN(DOUBLE); }                             // GCC
    234245__float80               { KEYWORD_RETURN(FLOAT80); }                    // GCC
    235246float80                 { KEYWORD_RETURN(FLOAT80); }                    // GCC
     247_Float128               { KEYWORD_RETURN(FLOAT128); }                   // GCC
     248_Float128x              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    236249__float128              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    237250float128                { KEYWORD_RETURN(FLOAT128); }                   // GCC
     
    446459
    447460%%
     461
    448462// ----end of lexer----
    449463
    450464void yyerror( const char * errmsg ) {
     465        SemanticErrorThrow = true;
    451466        cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
    452467                 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
  • src/Parser/parser.yy

    r0182bfa r28f3a19  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 24 18:11:59 2018
    13 // Update Count     : 3369
     12// Last Modified On : Fri Jun 22 13:59:11 2018
     13// Update Count     : 3586
    1414//
    1515
     
    136136} // build_postfix_name
    137137
    138 bool forall = false, xxx = false;                                               // aggregate have one or more forall qualifiers ?
     138bool forall = false, xxx = false, yyy = false;                  // aggregate have one or more forall qualifiers ?
    139139
    140140// https://www.gnu.org/software/bison/manual/bison.html#Location-Type
     
    175175        bool flag;
    176176        CatchStmt::Kind catch_kind;
     177        GenericExpr * genexpr;
    177178}
    178179
     
    259260%type<flag> asm_volatile_opt
    260261%type<en> handler_predicate_opt
     262%type<genexpr> generic_association generic_assoc_list
    261263
    262264// statements
    263265%type<sn> statement                                             labeled_statement                       compound_statement
    264266%type<sn> statement_decl                                statement_decl_list                     statement_list_nodecl
    265 %type<sn> selection_statement
     267%type<sn> selection_statement                   if_statement
    266268%type<sn> switch_clause_list_opt                switch_clause_list
    267269%type<en> case_value
     
    302304%type<en> enumerator_value_opt
    303305
    304 %type<decl> exception_declaration external_definition external_definition_list external_definition_list_opt
     306%type<decl> external_definition external_definition_list external_definition_list_opt
     307
     308%type<decl> exception_declaration
    305309
    306310%type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list
     
    324328%type<decl> cfa_identifier_parameter_declarator_tuple cfa_identifier_parameter_ptr
    325329
    326 %type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_type_list_opt
     330%type<decl> cfa_parameter_declaration cfa_parameter_list cfa_parameter_ellipsis_list_opt
    327331
    328332%type<decl> cfa_typedef_declaration cfa_variable_declaration cfa_variable_specifier
     
    330334%type<decl> c_declaration static_assert
    331335%type<decl> KR_function_declarator KR_function_no_ptr KR_function_ptr KR_function_array
    332 %type<decl> KR_declaration_list KR_declaration_list_opt
     336%type<decl> KR_parameter_list KR_parameter_list_opt
    333337
    334338%type<decl> parameter_declaration parameter_list parameter_type_list_opt
     
    402406//************************* Namespace Management ********************************
    403407
    404 // The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols
    405 // "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical.  While it is possible to write a purely
    406 // context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.
    407 // Hence, this grammar uses the ANSI style.
    408 //
    409 // Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those
    410 // introduced through "forall" qualifiers), and by introducing "type generators" -- parameterized types.  This latter
    411 // type name creates a third class of identifiers that must be distinguished by the scanner.
    412 //
    413 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, it
    414 // accesses a data structure (TypedefTable) to allow classification of an identifier that it has just read.  Semantic
    415 // actions during the parser update this data structure when the class of identifiers change.
    416 //
    417 // Because the Cforall language is block-scoped, an identifier can change its class in a local scope; it must revert to
    418 // its original class at the end of the block.  Since type names can be local to a particular declaration, each
    419 // declaration is itself a scope.  This requires distinguishing between type names that are local to the current
    420 // declaration scope and those that persist past the end of the declaration (i.e., names defined in "typedef" or "otype"
    421 // declarations).
    422 //
    423 // The non-terminals "push" and "pop" denote the opening and closing of scopes.  Every push must have a matching pop,
    424 // although it is regrettable the matching pairs do not always occur within the same rule.  These non-terminals may
    425 // appear in more contexts than strictly necessary from a semantic point of view.
     408// The C grammar is not context free because it relies on the distinct terminal symbols "identifier" and "TYPEDEFname",
     409// which are lexically identical.
     410//
     411//   typedef int foo; // identifier foo must now be scanned as TYPEDEFname
     412//   foo f;           // to allow it to appear in this context
     413//
     414// While it may be possible to write a purely context-free grammar, such a grammar would obscure the relationship
     415// between syntactic and semantic constructs.  Cforall compounds this problem by introducing type names local to the
     416// scope of a declaration (for instance, those introduced through "forall" qualifiers), and by introducing "type
     417// generators" -- parameterized types.  This latter type name creates a third class of identifiers, "TYPEGENname", which
     418// must be distinguished by the lexical scanner.
     419//
     420// Since the scanner cannot distinguish among the different classes of identifiers without some context information,
     421// there is a type table (typedefTable), which holds type names and identifiers that override type names, for each named
     422// scope. During parsing, semantic actions update the type table by adding new identifiers in the current scope. For
     423// each context that introduces a name scope, a new level is created in the type table and that level is popped on
     424// exiting the scope.  Since type names can be local to a particular declaration, each declaration is itself a scope.
     425// This requires distinguishing between type names that are local to the current declaration scope and those that
     426// persist past the end of the declaration (i.e., names defined in "typedef" or "otype" declarations).
     427//
     428// The non-terminals "push" and "pop" denote the opening and closing of named scopes. Every push has a matching pop in
     429// the production rule. There are multiple lists of declarations, where each declaration is a named scope, so pop/push
     430// around the list separator.
     431//
     432//  int f( forall(T) T (*f1) T , forall( S ) S (*f2)( S ) );
     433//      push               pop   push                   pop
    426434
    427435push:
     
    497505                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    498506        | type_name '.' no_attr_identifier                                      // CFA, nested type
    499                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     507                // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     508                { $$ = nullptr; }
    500509        | type_name '.' '[' field_list ']'                                      // CFA, nested type / tuple field selector
    501                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     510                // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     511                { $$ = nullptr; }
    502512        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    503                 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     513                {
     514                        // add the missing control expression to the GenericExpr and return it
     515                        $5->control = maybeMoveBuild<Expression>( $3 );
     516                        $$ = new ExpressionNode( $5 );
     517                }
    504518        ;
    505519
    506520generic_assoc_list:                                                                             // C11
    507         | generic_association
     521        generic_association
    508522        | generic_assoc_list ',' generic_association
     523                {
     524                        // steal the association node from the singleton and delete the wrapper
     525                        $1->associations.splice($1->associations.end(), $3->associations);
     526                        delete $3;
     527                        $$ = $1;
     528                }
    509529        ;
    510530
    511531generic_association:                                                                    // C11
    512532        type_no_function ':' assignment_expression
     533                {
     534                        // create a GenericExpr wrapper with one association pair
     535                        $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>($3) } } );
     536                }
    513537        | DEFAULT ':' assignment_expression
     538                { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>($3) } } ); }
    514539        ;
    515540
     
    623648                // semantics checks, e.g., ++3, 3--, *3, &&3
    624649        | constant
    625                 { $$ = $1; }
    626650        | string_literal
    627651                { $$ = new ExpressionNode( $1 ); }
     
    835859//      '[' ']'
    836860//              { $$ = new ExpressionNode( build_tuple() ); }
    837 //      '[' push assignment_expression pop ']'
     861//      | '[' push assignment_expression pop ']'
    838862//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    839         '[' push ',' tuple_expression_list pop ']'
    840                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $4 ) ) ); }
    841         | '[' push assignment_expression ',' tuple_expression_list pop ']'
    842                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $5 ) ) ); }
     863        '[' ',' tuple_expression_list ']'
     864                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     865        | '[' push assignment_expression pop ',' tuple_expression_list ']'
     866                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $6 ) ) ); }
    843867        ;
    844868
     
    892916        '{' '}'
    893917                { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
    894         | '{'
    895                 // Two scopes are necessary because the block itself has a scope, but every declaration within the block also
    896                 // requires its own scope.
    897           push push
     918        | '{' push
    898919          local_label_declaration_opt                                           // GCC, local labels
    899920          statement_decl_list                                                           // C99, intermix declarations and statements
    900921          pop '}'
    901                 { $$ = new StatementNode( build_compound( $5 ) ); }
     922                { $$ = new StatementNode( build_compound( $4 ) ); }
    902923        ;
    903924
    904925statement_decl_list:                                                                    // C99
    905926        statement_decl
    906         | statement_decl_list push statement_decl
    907                 { if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } }
     927        | statement_decl_list statement_decl
     928                { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
    908929        ;
    909930
     
    923944                        $$ = new StatementNode( $2 );
    924945                }
    925         | statement pop
     946        | statement
    926947        ;
    927948
     
    938959
    939960selection_statement:
    940         IF '(' push if_control_expression ')' statement         %prec THEN
    941                 // explicitly deal with the shift/reduce conflict on if/else
    942                 { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); }
    943         | IF '(' push if_control_expression ')' statement ELSE statement
    944                 { $$ = new StatementNode( build_if( $4, $6, $8 ) ); }
     961                        // pop causes a S/R conflict without separating the IF statement into a non-terminal even after resolving
     962                        // the inherent S/R conflict with THEN/ELSE.
     963        push if_statement pop
     964                { $$ = $2; }
    945965        | SWITCH '(' comma_expression ')' case_clause
    946966                { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
    947         | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
     967        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    948968                {
    949969                        StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     
    957977        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    958978                { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
    959         | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
     979        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    960980                {
    961981                        StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
     
    964984        ;
    965985
     986if_statement:
     987        IF '(' if_control_expression ')' statement                      %prec THEN
     988                // explicitly deal with the shift/reduce conflict on if/else
     989                { $$ = new StatementNode( build_if( $3, $5, nullptr ) ); }
     990        | IF '(' if_control_expression ')' statement ELSE statement
     991                { $$ = new StatementNode( build_if( $3, $5, $7 ) ); }
     992        ;
     993
    966994if_control_expression:
    967         comma_expression pop
     995        comma_expression
    968996                { $$ = new IfCtl( nullptr, $1 ); }
    969         | c_declaration pop                                                                     // no semi-colon
     997        | c_declaration                                                                         // no semi-colon
    970998                { $$ = new IfCtl( $1, nullptr ); }
    971         | cfa_declaration pop                                                           // no semi-colon
     999        | cfa_declaration                                                                       // no semi-colon
    9721000                { $$ = new IfCtl( $1, nullptr ); }
    9731001        | declaration comma_expression                                          // semi-colon separated
     
    10261054
    10271055iteration_statement:
    1028         WHILE '(' comma_expression ')' statement
    1029                 { $$ = new StatementNode( build_while( $3, $5 ) ); }
     1056        WHILE '(' push if_control_expression ')' statement pop
     1057                { $$ = new StatementNode( build_while( $4, $6 ) ); }
    10301058        | DO statement WHILE '(' comma_expression ')' ';'
    1031                 { $$ = new StatementNode( build_while( $5, $2, true ) ); }
    1032         | FOR '(' push for_control_expression ')' statement
     1059                { $$ = new StatementNode( build_do_while( $5, $2 ) ); }
     1060        | FOR '(' push for_control_expression ')' statement pop
    10331061                { $$ = new StatementNode( build_for( $4, $6 ) ); }
    10341062        ;
    10351063
    10361064for_control_expression:
    1037         comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt
    1038                 { $$ = new ForCtl( $1, $4, $6 ); }
     1065        comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt
     1066                { $$ = new ForCtl( $1, $3, $5 ); }
    10391067        | declaration comma_expression_opt ';' comma_expression_opt // C99
    10401068                { $$ = new ForCtl( $1, $2, $4 ); }
     
    11581186
    11591187handler_clause:
    1160         handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
    1161                 { $$ = new StatementNode( build_catch( $1, $5, $7, $9 ) ); }
    1162         | handler_clause handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
    1163                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, $8, $10 ) ) ); }
     1188        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     1189                { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1190        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     1191                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
    11641192        ;
    11651193
     
    12651293
    12661294declaration_list_opt:                                                                   // used at beginning of switch statement
    1267         pop     // empty
     1295        // empty
    12681296                { $$ = nullptr; }
    12691297        | declaration_list
     
    12721300declaration_list:
    12731301        declaration
    1274         | declaration_list push declaration
    1275                 { $$ = $1->appendList( $3 ); }
    1276         ;
    1277 
    1278 KR_declaration_list_opt:                                                                // used to declare parameter types in K&R style functions
     1302        | declaration_list declaration
     1303                { $$ = $1->appendList( $2 ); }
     1304        ;
     1305
     1306KR_parameter_list_opt:                                                                  // used to declare parameter types in K&R style functions
    12791307        // empty
    12801308                { $$ = nullptr; }
    1281         | KR_declaration_list
    1282         ;
    1283 
    1284 KR_declaration_list:
     1309        | KR_parameter_list
     1310        ;
     1311
     1312KR_parameter_list:
    12851313        push c_declaration pop ';'
    12861314                { $$ = $2; }
    1287         | KR_declaration_list push c_declaration pop ';'
     1315        | KR_parameter_list push c_declaration pop ';'
    12881316                { $$ = $1->appendList( $3 ); }
    12891317        ;
     
    13051333
    13061334declaration:                                                                                    // old & new style declarations
    1307         c_declaration pop ';'
    1308         | cfa_declaration pop ';'                                                       // CFA
    1309         | static_assert
     1335        c_declaration ';'
     1336        | cfa_declaration ';'                                                           // CFA
     1337        | static_assert                                                                         // C11
    13101338        ;
    13111339
     
    13131341        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    13141342                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
     1343        | STATICASSERT '(' constant_expression ')' ';'          // CFA
     1344                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
    13151345
    13161346// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    13571387cfa_function_declaration:                                                               // CFA
    13581388        cfa_function_specifier
    1359                 { $$ = $1; }
    13601389        | type_qualifier_list cfa_function_specifier
    13611390                { $$ = $2->addQualifiers( $1 ); }
     
    13641393        | declaration_qualifier_list type_qualifier_list cfa_function_specifier
    13651394                { $$ = $3->addQualifiers( $1 )->addQualifiers( $2 ); }
    1366         | cfa_function_declaration ',' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
     1395        | cfa_function_declaration ',' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
    13671396                {
    13681397                        // Append the return type at the start (left-hand-side) to each identifier in the list.
    13691398                        DeclarationNode * ret = new DeclarationNode;
    13701399                        ret->type = maybeClone( $1->type->base );
    1371                         $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $5, nullptr ) );
     1400                        $$ = $1->appendList( DeclarationNode::newFunction( $3, ret, $6, nullptr ) );
    13721401                }
    13731402        ;
    13741403
    13751404cfa_function_specifier:                                                                 // CFA
    1376 //      '[' ']' identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')' // S/R conflict
     1405//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    13771406//              {
    13781407//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
    13791408//              }
    1380 //      '[' ']' identifier '(' push cfa_parameter_type_list_opt pop ')'
     1409//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    13811410//              {
    13821411//                      typedefTable.setNextIdentifier( *$5 );
    13831412//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    13841413//              }
    1385 //      | '[' ']' TYPEDEFname '(' push cfa_parameter_type_list_opt pop ')'
     1414//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    13861415//              {
    13871416//                      typedefTable.setNextIdentifier( *$5 );
     
    13911420                // identifier_or_type_name must be broken apart because of the sequence:
    13921421                //
    1393                 //   '[' ']' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
     1422                //   '[' ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')'
    13941423                //   '[' ']' type_specifier
    13951424                //
    13961425                // type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
    13971426                // flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
    1398         cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
     1427        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
    13991428                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    14001429                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
    1401         | cfa_function_return identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
     1430        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')'
    14021431                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
    14031432        ;
     
    14141443        TYPEDEF cfa_variable_specifier
    14151444                {
    1416                         typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname );
     1445                        typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "1" );
    14171446                        $$ = $2->addTypedef();
    14181447                }
    14191448        | TYPEDEF cfa_function_specifier
    14201449                {
    1421                         typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname );
     1450                        typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "2" );
    14221451                        $$ = $2->addTypedef();
    14231452                }
    14241453        | cfa_typedef_declaration pop ',' push no_attr_identifier
    14251454                {
    1426                         typedefTable.addToEnclosingScope( *$5, TYPEDEFname );
     1455                        typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" );
    14271456                        $$ = $1->appendList( $1->cloneType( $5 ) );
    14281457                }
     
    14351464        TYPEDEF type_specifier declarator
    14361465                {
    1437                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname );
     1466                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    14381467                        $$ = $3->addType( $2 )->addTypedef();
    14391468                }
    14401469        | typedef_declaration pop ',' push declarator
    14411470                {
    1442                         typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname );
     1471                        typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname, "5" );
    14431472                        $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
    14441473                }
    14451474        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    14461475                {
    1447                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname );
     1476                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" );
    14481477                        $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
    14491478                }
    14501479        | type_specifier TYPEDEF declarator
    14511480                {
    1452                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname );
     1481                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" );
    14531482                        $$ = $3->addType( $1 )->addTypedef();
    14541483                }
    14551484        | type_specifier TYPEDEF type_qualifier_list declarator
    14561485                {
    1457                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname );
     1486                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
    14581487                        $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    14591488                }
     
    15821611
    15831612forall:
    1584         FORALL '(' push type_parameter_list pop ')'                                     // CFA
    1585                 { $$ = DeclarationNode::newForall( $4 ); }
     1613        FORALL '(' type_parameter_list ')'                                      // CFA
     1614                { $$ = DeclarationNode::newForall( $3 ); }
    15861615        ;
    15871616
     
    17651794                { $$ = DeclarationNode::newFromTypedef( $1 ); }
    17661795        | '.' TYPEDEFname
    1767                 { $$ = DeclarationNode::newFromTypedef( $2 ); } // FIX ME
     1796                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    17681797        | type_name '.' TYPEDEFname
    1769                 { $$ = DeclarationNode::newFromTypedef( $3 ); } // FIX ME
     1798                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    17701799        | typegen_name
    17711800        | '.' typegen_name
    1772                 { $$ = $2; }                                                                    // FIX ME
     1801                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    17731802        | type_name '.' typegen_name
    1774                 { $$ = $3; }                                                                    // FIX ME
     1803                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    17751804        ;
    17761805
     
    17941823        ;
    17951824
     1825fred:
     1826        // empty
     1827                { yyy = false; }
     1828        ;
     1829
    17961830aggregate_type:                                                                                 // struct, union
    17971831        aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
    17981832                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
    1799         | aggregate_key attribute_list_opt no_attr_identifier_or_type_name
    1800                 {
    1801                         typedefTable.makeTypedef( *$3 );                        // create typedef
    1802                         if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
     1833        | aggregate_key attribute_list_opt no_attr_identifier fred
     1834                {
     1835                        typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef
     1836                        //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
    18031837                        forall = false;                                                         // reset
    18041838                }
    18051839          '{' field_declaration_list_opt '}'
    1806                 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
     1840                { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $7, true )->addQualifiers( $2 ); }
     1841        | aggregate_key attribute_list_opt type_name fred
     1842                {
     1843                        typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef
     1844                        //if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update
     1845                        forall = false;                                                         // reset
     1846                }
     1847          '{' field_declaration_list_opt '}'
     1848                { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $7, true )->addQualifiers( $2 ); }
    18071849        | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
    18081850                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
     
    18111853
    18121854aggregate_type_nobody:                                                                  // struct, union - {...}
    1813         aggregate_key attribute_list_opt no_attr_identifier
    1814                 {
    1815                         typedefTable.makeTypedef( *$3 );
    1816                         if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
     1855        aggregate_key attribute_list_opt no_attr_identifier fred
     1856                {
     1857                        typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname );
     1858                        //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
    18171859                        forall = false;                                                         // reset
    18181860                        $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 );
    18191861                }
    1820         | aggregate_key attribute_list_opt TYPEDEFname
    1821                 {
    1822                         typedefTable.makeTypedef( *$3 );
    1823                         $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 );
    1824                 }
    1825         | aggregate_key attribute_list_opt typegen_name         // CFA
     1862        | aggregate_key attribute_list_opt type_name fred
    18261863                {
    18271864                        // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is
     
    18371874aggregate_key:
    18381875        STRUCT
    1839                 { $$ = DeclarationNode::Struct; }
     1876                { yyy = true; $$ = DeclarationNode::Struct; }
    18401877        | UNION
    1841                 { $$ = DeclarationNode::Union; }
     1878                { yyy = true; $$ = DeclarationNode::Union; }
    18421879        | EXCEPTION
    1843                 { $$ = DeclarationNode::Exception; }
     1880                { yyy = true; $$ = DeclarationNode::Exception; }
    18441881        | COROUTINE
    1845                 { $$ = DeclarationNode::Coroutine; }
     1882                { yyy = true; $$ = DeclarationNode::Coroutine; }
    18461883        | MONITOR
    1847                 { $$ = DeclarationNode::Monitor; }
     1884                { yyy = true; $$ = DeclarationNode::Monitor; }
    18481885        | THREAD
    1849                 { $$ = DeclarationNode::Thread; }
     1886                { yyy = true; $$ = DeclarationNode::Thread; }
    18501887        ;
    18511888
     
    18581895
    18591896field_declaration:
    1860         cfa_field_declaring_list ';'                                            // CFA, new style field declaration
     1897        type_specifier field_declaring_list ';'
     1898                { $$ = distAttr( $1, $2 ); }
     1899        | EXTENSION type_specifier field_declaring_list ';'     // GCC
     1900                { distExt( $3 ); $$ = distAttr( $2, $3 ); }             // mark all fields in list
     1901        | typedef_declaration ';'                                                       // CFA
     1902                { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }
     1903        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
    18611904        | EXTENSION cfa_field_declaring_list ';'                        // GCC
    1862                 {
    1863                         distExt( $2 );                                                          // mark all fields in list
    1864                         $$ = $2;
    1865                 }
    1866         | type_specifier field_declaring_list ';'
    1867                 {
    1868                         $$ = distAttr( $1, $2 ); }
    1869         | EXTENSION type_specifier field_declaring_list ';'     // GCC
    1870                 {
    1871                         distExt( $3 );                                                          // mark all fields in list
    1872                         $$ = distAttr( $2, $3 );
    1873                 }
    1874         | static_assert
     1905                { distExt( $2 ); $$ = $2; }                                             // mark all fields in list
     1906        | cfa_typedef_declaration ';'                                           // CFA
     1907                { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }
     1908        | static_assert                                                                         // C11
    18751909        ;
    18761910
     
    19111945                { $$ = nullptr; }
    19121946        | bit_subrange_size
    1913                 { $$ = $1; }
    19141947        ;
    19151948
     
    19221955        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    19231956                { $$ = DeclarationNode::newEnum( new string( DeclarationNode::anonymous.newName() ), $4, true )->addQualifiers( $2 ); }
    1924         | ENUM attribute_list_opt no_attr_identifier_or_type_name
     1957        | ENUM attribute_list_opt no_attr_identifier
    19251958                { typedefTable.makeTypedef( *$3 ); }
    19261959          '{' enumerator_list comma_opt '}'
    19271960                { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); }
     1961        | ENUM attribute_list_opt type_name
     1962          '{' enumerator_list comma_opt '}'
     1963                { $$ = DeclarationNode::newEnum( $3->type->symbolic.name, $5, true )->addQualifiers( $2 ); }
    19281964        | enum_type_nobody
    19291965        ;
    19301966
    19311967enum_type_nobody:                                                                               // enum - {...}
    1932         ENUM attribute_list_opt no_attr_identifier_or_type_name
     1968        ENUM attribute_list_opt no_attr_identifier
    19331969                {
    19341970                        typedefTable.makeTypedef( *$3 );
    19351971                        $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 );
     1972                }
     1973        | ENUM attribute_list_opt type_name
     1974                {
     1975                        typedefTable.makeTypedef( *$3->type->symbolic.name );
     1976                        $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 );
    19361977                }
    19371978        ;
     
    19511992        ;
    19521993
    1953 cfa_parameter_type_list_opt:                                                    // CFA, abstract + real
     1994cfa_parameter_ellipsis_list_opt:                                                        // CFA, abstract + real
    19541995        // empty
    19551996                { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); }
     
    20842125                { $$ = $2; }
    20852126        | '=' VOID
    2086                 { $$ = nullptr; }
     2127                { $$ = new InitializerNode( true ); }
    20872128        | ATassign initializer
    20882129                { $$ = $2->set_maybeConstructed( false ); }
     
    21612202type_parameter_list:                                                                    // CFA
    21622203        type_parameter
    2163                 { $$ = $1; }
    21642204        | type_parameter_list ',' type_parameter
    21652205                { $$ = $1->appendList( $3 ); }
     
    21752215type_parameter:                                                                                 // CFA
    21762216        type_class no_attr_identifier_or_type_name
    2177                 { typedefTable.addToEnclosingScope( *$2, TYPEDEFname ); }
     2217                { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); }
    21782218          type_initializer_opt assertion_list_opt
    21792219                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
     
    22092249        '|' no_attr_identifier_or_type_name '(' type_list ')'
    22102250                { $$ = DeclarationNode::newTraitUse( $2, $4 ); }
    2211         | '|' '{' push trait_declaration_list '}'
     2251        | '|' '{' push trait_declaration_list pop '}'
    22122252                { $$ = $4; }
    2213         | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}' '(' type_list ')'
    2214                 { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
     2253        // | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')'
     2254        //      { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
    22152255        ;
    22162256
     
    22442284        no_attr_identifier_or_type_name
    22452285                {
    2246                         typedefTable.addToEnclosingScope( *$1, TYPEDEFname );
     2286                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    22472287                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    22482288                }
    2249         | no_attr_identifier_or_type_name '(' push type_parameter_list pop ')'
    2250                 {
    2251                         typedefTable.addToEnclosingScope( *$1, TYPEGENname );
    2252                         $$ = DeclarationNode::newTypeDecl( $1, $4 );
     2289        | no_attr_identifier_or_type_name '(' type_parameter_list ')'
     2290                {
     2291                        typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" );
     2292                        $$ = DeclarationNode::newTypeDecl( $1, $3 );
    22532293                }
    22542294        ;
    22552295
    22562296trait_specifier:                                                                                // CFA
    2257         TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}'
    2258                 { $$ = DeclarationNode::newTrait( $2, $5, 0 ); }
    2259         | TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}'
    2260                 { $$ = DeclarationNode::newTrait( $2, $5, $10 ); }
     2297        TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}'
     2298                { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
     2299        | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
     2300                { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
    22612301        ;
    22622302
    22632303trait_declaration_list:                                                                 // CFA
    22642304        trait_declaration
    2265         | trait_declaration_list push trait_declaration
    2266                 { $$ = $1->appendList( $3 ); }
     2305        | trait_declaration_list pop push trait_declaration
     2306                { $$ = $1->appendList( $4 ); }
    22672307        ;
    22682308
    22692309trait_declaration:                                                                              // CFA
    2270         cfa_trait_declaring_list pop ';'
    2271         | trait_declaring_list pop ';'
     2310        cfa_trait_declaring_list ';'
     2311        | trait_declaring_list ';'
    22722312        ;
    22732313
     
    22892329
    22902330translation_unit:
    2291         // empty
    2292                 {}                                                                                              // empty input file
     2331        // empty, input file
    22932332        | external_definition_list
    22942333                { parseTree = parseTree ? parseTree->appendList( $1 ) : $1;     }
     
    22962335
    22972336external_definition_list:
    2298         external_definition
     2337        push external_definition pop
     2338                { $$ = $2; }
    22992339        | external_definition_list
    23002340                { forall = xxx; }
    2301           push external_definition
     2341          push external_definition pop
    23022342                { $$ = $1 ? $1->appendList( $4 ) : $4; }
    23032343        ;
     
    23092349        ;
    23102350
     2351up:
     2352                { typedefTable.up(); }
     2353        ;
     2354
     2355down:
     2356                { typedefTable.down(); }
     2357        ;
     2358
    23112359external_definition:
    23122360        declaration
    23132361        | external_function_definition
     2362        | EXTENSION external_definition                                         // GCC, multiple __extension__ allowed, meaning unknown
     2363                {
     2364                        distExt( $2 );                                                          // mark all fields in list
     2365                        $$ = $2;
     2366                }
    23142367        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    23152368                {
     
    23212374                        linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
    23222375                }
    2323           '{' external_definition_list_opt '}'
     2376          '{' up external_definition_list_opt down '}'
    23242377                {
    23252378                        linkage = linkageStack.top();
    23262379                        linkageStack.pop();
    2327                         $$ = $5;
    2328                 }
    2329         | EXTENSION external_definition                                         // GCC, multiple __extension__ allowed, meaning unknown
    2330                 {
    2331                         distExt( $2 );                                                          // mark all fields in list
    2332                         $$ = $2;
     2380                        $$ = $6;
    23332381                }
    23342382        | type_qualifier_list
    2335                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2336           push '{' external_definition_list '}'                         // CFA, namespace
     2383                {
     2384                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2385                        if ( $1->type->forall ) xxx = forall = true; // remember generic type
     2386                }
     2387          '{' up external_definition_list_opt down '}'          // CFA, namespace
    23372388                {
    23382389                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     
    23462397                }
    23472398        | declaration_qualifier_list
    2348                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2349           push '{' external_definition_list '}'                         // CFA, namespace
     2399                {
     2400                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2401                        if ( $1->type->forall ) xxx = forall = true; // remember generic type
     2402                }
     2403          '{' up external_definition_list_opt down '}'          // CFA, namespace
    23502404                {
    23512405                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     
    23602414        | declaration_qualifier_list type_qualifier_list
    23612415                {
    2362                         // forall must be in the type_qualifier_list
    2363                         if ( $2->type->forall ) xxx = forall = true; // remember generic type
    2364                 }
    2365           push '{' external_definition_list '}'                         // CFA, namespace
     2416                        if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2417                        if ( ($1->type && $1->type->forall) || $2->type->forall ) xxx = forall = true; // remember generic type
     2418                }
     2419          '{' up external_definition_list_opt down '}'          // CFA, namespace
    23662420                {
    23672421                        for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     
    23872441        | function_declarator compound_statement
    23882442                { $$ = $1->addFunctionBody( $2 ); }
    2389         | KR_function_declarator KR_declaration_list_opt compound_statement
     2443        | KR_function_declarator KR_parameter_list_opt compound_statement
    23902444                { $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 ); }
    23912445        ;
     
    24272481
    24282482                // Old-style K&R function definition, OBSOLESCENT (see 4)
    2429         | declaration_specifier KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2483        | declaration_specifier KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    24302484                {
    24312485                        rebindForall( $1, $2 );
     
    24332487                }
    24342488                // handles default int return type, OBSOLESCENT (see 1)
    2435         | type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2489        | type_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    24362490                { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
    24372491                // handles default int return type, OBSOLESCENT (see 1)
    2438         | declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2492        | declaration_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    24392493                { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
    24402494                // handles default int return type, OBSOLESCENT (see 1)
    2441         | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
     2495        | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_parameter_list_opt with_clause_opt compound_statement
    24422496                { $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); }
    24432497        ;
     
    26842738        typedef
    26852739                // hide type name in enclosing scope by variable name
    2686                 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER ); }
     2740                { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" ); }
    26872741        | '(' paren_type ')'
    26882742                { $$ = $2; }
     
    29743028        '[' ']'
    29753029                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    2976         // multi_array_dimension handles the '[' '*' ']' case
     3030                // multi_array_dimension handles the '[' '*' ']' case
    29773031        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    29783032                { $$ = DeclarationNode::newVarArray( $3 ); }
    29793033        | '[' push type_qualifier_list pop ']'
    29803034                { $$ = DeclarationNode::newArray( 0, $3, false ); }
    2981         // multi_array_dimension handles the '[' assignment_expression ']' case
     3035                // multi_array_dimension handles the '[' assignment_expression ']' case
    29823036        | '[' push type_qualifier_list assignment_expression pop ']'
    29833037                { $$ = DeclarationNode::newArray( $4, $3, false ); }
     
    31153169//
    31163170//              cfa_abstract_tuple identifier_or_type_name
    3117 //              '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
     3171//              '[' cfa_parameter_list ']' identifier_or_type_name '(' cfa_parameter_ellipsis_list_opt ')'
    31183172//
    31193173// since a function return type can be syntactically identical to a tuple type:
     
    31743228        '[' push cfa_abstract_parameter_list pop ']'
    31753229                { $$ = DeclarationNode::newTuple( $3 ); }
     3230        | '[' push type_specifier_nobody ELLIPSIS pop ']'
     3231                { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; }
     3232        | '[' push type_specifier_nobody ELLIPSIS constant_expression pop ']'
     3233                { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; }
    31763234        ;
    31773235
    31783236cfa_abstract_function:                                                                  // CFA
    3179 //      '[' ']' '(' cfa_parameter_type_list_opt ')'
     3237//      '[' ']' '(' cfa_parameter_ellipsis_list_opt ')'
    31803238//              { $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }
    3181         cfa_abstract_tuple '(' push cfa_parameter_type_list_opt pop ')'
     3239        cfa_abstract_tuple '(' push cfa_parameter_ellipsis_list_opt pop ')'
    31823240                { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
    3183         | cfa_function_return '(' push cfa_parameter_type_list_opt pop ')'
     3241        | cfa_function_return '(' push cfa_parameter_ellipsis_list_opt pop ')'
    31843242                { $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
    31853243        ;
     
    32123270
    32133271%%
     3272
    32143273// ----end of grammar----
    32153274
  • src/ResolvExpr/Alternative.cc

    r0182bfa r28f3a19  
    3030
    3131namespace ResolvExpr {
    32         Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( 0 ) {}
     32        Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ) {}
    3333
    3434        Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
  • src/ResolvExpr/AlternativeFinder.cc

    r0182bfa r28f3a19  
    9898                void postvisit( InitExpr * initExpr );
    9999                void postvisit( DeletedExpr * delExpr );
     100                void postvisit( GenericExpr * genExpr );
    100101
    101102                /// Adds alternatives for anonymous members
     
    175176                                                selected[ mangleName ] = current;
    176177                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    177                                                 PRINT(
    178                                                         std::cerr << "marking ambiguous" << std::endl;
    179                                                 )
    180                                                 mapPlace->second.isAmbiguous = true;
     178                                                // if one of the candidates contains a deleted identifier, can pick the other, since
     179                                                // deleted expressions should not be ambiguous if there is another option that is at least as good
     180                                                if ( findDeletedExpr( candidate->expr ) ) {
     181                                                        // do nothing
     182                                                        PRINT( std::cerr << "candidate is deleted" << std::endl; )
     183                                                } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) {
     184                                                        PRINT( std::cerr << "current is deleted" << std::endl; )
     185                                                        selected[ mangleName ] = current;
     186                                                } else {
     187                                                        PRINT(
     188                                                                std::cerr << "marking ambiguous" << std::endl;
     189                                                        )
     190                                                        mapPlace->second.isAmbiguous = true;
     191                                                }
    181192                                        } else {
    182193                                                PRINT(
     
    298309                // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
    299310                Expression* aggrExpr = alt.expr->clone();
    300                 alt.env.apply( aggrExpr->get_result() );
    301                 Type * aggrType = aggrExpr->get_result();
     311                alt.env.apply( aggrExpr->result );
     312                Type * aggrType = aggrExpr->result;
    302313                if ( dynamic_cast< ReferenceType * >( aggrType ) ) {
    303314                        aggrType = aggrType->stripReferences();
     
    305316                }
    306317
    307                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
     318                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    308319                        addAggMembers( structInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
    309                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
     320                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    310321                        addAggMembers( unionInst, aggrExpr, alt.cost+Cost::safe, alt.env, "" );
    311322                } // if
     
    317328                aggInst->lookup( name, members );
    318329
    319                 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    320                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    321                                 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    322                                 renameTypes( alternatives.back().expr );
    323                                 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     330                for ( Declaration * decl : members ) {
     331                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     332                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     333                                // can't construct in place and use vector::back
     334                                Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
     335                                renameTypes( newAlt.expr );
     336                                addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     337                                alternatives.push_back( std::move(newAlt) );
    324338                        } else {
    325339                                assert( false );
     
    331345                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    332346                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    333                         // xxx - this should be improved by memoizing the value of constant exprs
    334                         // during parsing and reusing that information here.
    335                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    336                         int val = 0;
     347                        auto val = constantExpr->intValue();
    337348                        std::string tmp;
    338                         if ( ss >> val && ! (ss >> tmp) ) {
    339                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    340                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
    341                                 } // if
     349                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
     350                                alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    342351                        } // if
    343                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    344                         // xxx - temporary hack until 0/1 are int constants
    345                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    346                                 std::stringstream ss( nameExpr->get_name() );
    347                                 int val;
    348                                 ss >> val;
    349                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr, val ), env, newCost ) );
    350                         }
    351352                } // if
    352353        }
     
    435436                                        return Cost::infinity;
    436437                                }
     438                        }
     439                        if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {
     440                                // default arguments should be free - don't include conversion cost.
     441                                // Unwrap them here because they are not relevant to the rest of the system.
     442                                *actualExpr = def->expr;
     443                                ++formal;
     444                                continue;
    437445                        }
    438446                        Type * formalType = (*formal)->get_type();
     
    604612        ConstantExpr* getDefaultValue( Initializer* init ) {
    605613                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
    606                         if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
    607                                 return dynamic_cast<ConstantExpr*>( ce->get_arg() );
     614                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) {
     615                                return dynamic_cast<ConstantExpr*>( ce->arg );
     616                        } else {
     617                                return dynamic_cast<ConstantExpr*>( si->value );
    608618                        }
    609619                }
     
    866876                                                                indexer ) ) {
    867877                                                        results.emplace_back(
    868                                                                 i, cnstExpr, move(env), move(need), move(have),
     878                                                                i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
    869879                                                                move(openVars), nextArg, nTuples );
    870880                                                }
     
    10581068                funcFinder.findWithAdjustment( untypedExpr->function );
    10591069                // if there are no function alternatives, then proceeding is a waste of time.
     1070                // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.
    10601071                if ( funcFinder.alternatives.empty() ) return;
    10611072
     
    10851096                        argExpansions.emplace_back();
    10861097                        auto& argE = argExpansions.back();
    1087                         argE.reserve( arg.alternatives.size() );
     1098                        // argE.reserve( arg.alternatives.size() );
    10881099
    10891100                        for ( const Alternative& actual : arg ) {
     
    11081119                                                        std::back_inserter( candidates ) );
    11091120                                        }
    1110                                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    1111                                         if ( const EqvClass *eqvClass = func->env.lookup( typeInst->get_name() ) ) {
     1121                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
     1122                                        if ( const EqvClass *eqvClass = func->env.lookup( typeInst->name ) ) {
    11121123                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass->type ) ) {
    11131124                                                        Alternative newFunc( *func );
     
    13641375                        Cost cost = Cost::zero;
    13651376                        Expression * newExpr = data.combine( cost );
    1366                         alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
     1377
     1378                        // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
     1379                        // can't construct in place and use vector::back
     1380                        Alternative newAlt( newExpr, env, Cost::zero, cost );
    13671381                        PRINT(
    13681382                                std::cerr << "decl is ";
     
    13731387                                std::cerr << std::endl;
    13741388                        )
    1375                         renameTypes( alternatives.back().expr );
    1376                         addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1389                        renameTypes( newAlt.expr );
     1390                        addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
     1391                        alternatives.push_back( std::move(newAlt) );
    13771392                } // for
    13781393        }
     
    17411756                assertf( false, "AlternativeFinder should never see a DeletedExpr." );
    17421757        }
     1758
     1759        void AlternativeFinder::Finder::postvisit( GenericExpr * ) {
     1760                assertf( false, "_Generic is not yet supported." );
     1761        }
    17431762} // namespace ResolvExpr
    17441763
  • src/ResolvExpr/CommonType.cc

    r0182bfa r28f3a19  
    2424#include "SynTree/Type.h"                // for BasicType, BasicType::Kind::...
    2525#include "SynTree/Visitor.h"             // for Visitor
    26 #include "Unify.h"                       // for unifyExact, bindVar, WidenMode
     26#include "Unify.h"                       // for unifyExact, WidenMode
    2727#include "typeops.h"                     // for isFtype
    2828
     
    176176        }
    177177
    178         static const BasicType::Kind combinedType[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] =
     178        static const BasicType::Kind combinedType[][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    179179        {
    180 /*              Bool            Char    SignedChar      UnsignedChar    ShortSignedInt  ShortUnsignedInt        SignedInt       UnsignedInt     LongSignedInt   LongUnsignedInt LongLongSignedInt       LongLongUnsignedInt     Float   Double  LongDouble      FloatComplex    DoubleComplex   LongDoubleComplex       FloatImaginary  DoubleImaginary LongDoubleImaginary   SignedInt128   UnsignedInt128 */
    181                 /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    182                 /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    183                 /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    184                 /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    185                 /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    186                 /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    187                 /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    188                 /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    189                 /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    190                 /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    191                 /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    192                 /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    193                 /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Float,       BasicType::Float, },
    194                 /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Double,      BasicType::Double, },
    195                 /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDouble,  BasicType::LongDouble, },
    196                 /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::FloatComplex, },
    197                 /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex, },
    198                 /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex, },
    199                 /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::FloatImaginary,      BasicType::FloatImaginary, },
    200                 /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::DoubleImaginary,     BasicType::DoubleImaginary, },
    201                 /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary },
    202                 /* SignedInt128 */      { BasicType::SignedInt128,      BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, },
    203                 /* UnsignedInt128 */    { BasicType::UnsignedInt128,    BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::UnsignedInt128,      BasicType::UnsignedInt128, },
     180/*              Bool            Char    SignedChar      UnsignedChar    ShortSignedInt  ShortUnsignedInt        SignedInt       UnsignedInt     LongSignedInt   LongUnsignedInt LongLongSignedInt       LongLongUnsignedInt     Float   Double  LongDouble      FloatComplex    DoubleComplex   LongDoubleComplex       FloatImaginary  DoubleImaginary LongDoubleImaginary   SignedInt128   UnsignedInt128   Float80   Float128 */
     181                /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     182                /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     183                /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     184                /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     185                /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     186                /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     187                /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     188                /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     189                /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     190                /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     191                /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     192                /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
     193                /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Float,       BasicType::Float, BasicType::Float80, BasicType::Float128 },
     194                /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Double,      BasicType::Double, BasicType::Float80, BasicType::Float128 },
     195                /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDouble,  BasicType::LongDouble, BasicType::BasicType::LongDouble, BasicType::Float128 },
     196                /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::FloatComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, },
     197                /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex },
     198                /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, },
     199                /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::FloatImaginary,      BasicType::FloatImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
     200                /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::DoubleImaginary,     BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
     201                /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
     202                /* SignedInt128 */      { BasicType::SignedInt128,      BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, },
     203                /* UnsignedInt128 */    { BasicType::UnsignedInt128,    BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::UnsignedInt128,      BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, },
     204                /* Float80 */   { BasicType::Float80,   BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::Float80,     BasicType::Float80, BasicType::Float80, BasicType::Float128 },
     205                /* Float128 */  { BasicType::Float128,  BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::Float128,    BasicType::Float128, BasicType::Float128, BasicType::Float128 },
    204206        };
     207        static_assert(
     208                sizeof(combinedType)/sizeof(combinedType[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     209                "Each basic type kind should have a corresponding row in the combined type matrix"
     210        );
    205211
    206212        CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
     
    232238                                AssertionSet need, have;
    233239                                WidenMode widen( widenFirst, widenSecond );
    234                                 if ( entry != openVars.end() && ! bindVar(var, voidPointer->get_base(), entry->second, env, need, have, openVars, widen, indexer ) ) return;
     240                                if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return;
    235241                        }
    236242                }
  • src/ResolvExpr/ConversionCost.cc

    r0182bfa r28f3a19  
    229229*/
    230230
    231         static const int costMatrix[ BasicType::NUMBER_OF_BASIC_TYPES ][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
    232         /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128 */
    233                 /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,     },
    234                 /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,     },
    235                 /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,     },
    236                 /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,      },
    237                 /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,      },
    238                 /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,      },
    239                 /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,      },
    240                 /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,      },
    241                 /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,      },
    242                 /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,      },
    243                 /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,      },
    244                 /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,      },
    245 
    246                 /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,     },
    247                 /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,     },
    248                 /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,     },
    249                 /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,     },
    250                 /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,     },
    251                 /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,     },
    252                 /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,     },
    253                 /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,     },
    254                 /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0,              -1,             -1,     },
    255 
    256                 /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,      },
    257                 /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,      },
     231        static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
     232        /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128, F80, F128 */
     233                /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,       14,   15},
     234                /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
     235                /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
     236                /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,        12,   13},
     237                /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,        11,   12},
     238                /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,        10,   11},
     239                /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,        9,    10},
     240                /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
     241                /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
     242                /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,        7,    8},
     243                /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,        6,    7},
     244                /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,        5,    6},
     245
     246                /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,       2,    3},
     247                /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,       1,    2},
     248                /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       -1,   1},
     249                /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
     250                /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
     251                /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
     252                /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,       -1,   -1},
     253                /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,       -1,   -1},
     254                /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0,              -1,             -1,       -1,   -1},
     255
     256                /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,        4,    4},
     257                /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,        3,    3},
     258
     259                /* F80 */       { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       0,    1},
     260                /* F128 */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       -1,   0},
    258261        };
     262        static_assert(
     263                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     264                "Each basic type kind should have a corresponding row in the cost matrix"
     265        );
     266
    259267
    260268        void ConversionCost::postvisit( VoidType * ) {
  • src/ResolvExpr/ExplodedActual.h

    r0182bfa r28f3a19  
    3131
    3232                ExplodedActual() : env(), cost(Cost::zero), exprs() {}
    33 
    3433                ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer );
     34                ExplodedActual(ExplodedActual&&) = default;
     35                ExplodedActual& operator= (ExplodedActual&&) = default;
    3536        };
    3637}
  • src/ResolvExpr/Resolver.cc

    r0182bfa r28f3a19  
    211211                        if ( findDeletedExpr( choice.expr ) ) {
    212212                                trace( choice.expr );
    213                                 SemanticError( choice.expr, "Unique best alternative includes deleted identifier in " );
     213                                SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " );
    214214                        }
    215215                        alt = std::move( choice );
     
    246246
    247247                auto untyped = new CastExpr{ expr }; // cast to void
     248                untyped->location = expr->location;
    248249
    249250                // set up and resolve expression cast to void
     
    271272        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer ) {
    272273                assert( untyped && type );
     274                // transfer location to generated cast for error purposes
     275                CodeLocation location = untyped->location;
    273276                untyped = new CastExpr( untyped, type );
     277                untyped->location = location;
    274278                findSingleExpression( untyped, indexer );
    275279                removeExtraneousCast( untyped, indexer );
     
    574578
    575579                                                        // Make sure we don't widen any existing bindings
    576                                                         for ( auto & i : resultEnv ) {
    577                                                                 i.allowWidening = false;
    578                                                         }
    579 
     580                                                        resultEnv.forbidWidening();
     581                                                       
    580582                                                        // Find any unbound type variables
    581583                                                        resultEnv.extractOpenVars( openVars );
  • src/ResolvExpr/Resolver.h

    r0182bfa r28f3a19  
    3636        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3737        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
     38        /// Searches expr and returns the first DeletedExpr found, otherwise nullptr
     39        DeletedExpr * findDeletedExpr( Expression * expr );
    3840} // namespace ResolvExpr
    3941
  • src/ResolvExpr/TypeEnvironment.cc

    r0182bfa r28f3a19  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:19:47 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 12:23:36 2015
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    2424#include "SynTree/Type.h"              // for Type, FunctionType, Type::Fora...
    2525#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
     26#include "Tuples/Tuples.h"             // for isTtype
    2627#include "TypeEnvironment.h"
     28#include "typeops.h"                   // for occurs
     29#include "Unify.h"                     // for unifyInexact
    2730
    2831namespace ResolvExpr {
     
    4649
    4750        void EqvClass::initialize( const EqvClass &src, EqvClass &dest ) {
     51                initialize( src, dest, src.type );
     52        }
     53
     54        void EqvClass::initialize( const EqvClass &src, EqvClass &dest, const Type *ty ) {
    4855                dest.vars = src.vars;
    49                 dest.type = maybeClone( src.type );
     56                dest.type = maybeClone( ty );
    5057                dest.allowWidening = src.allowWidening;
    5158                dest.data = src.data;
    5259        }
    5360
    54         EqvClass::EqvClass() : type( 0 ), allowWidening( true ) {
     61        EqvClass::EqvClass() : type( nullptr ), allowWidening( true ) {
    5562        }
    5663
    5764        EqvClass::EqvClass( const EqvClass &other ) {
    5865                initialize( other, *this );
     66        }
     67
     68        EqvClass::EqvClass( const EqvClass &other, const Type *ty ) {
     69                initialize( other, *this, ty );
     70        }
     71
     72        EqvClass::EqvClass( EqvClass &&other )
     73        : vars{std::move(other.vars)}, type{other.type},
     74          allowWidening{std::move(other.allowWidening)}, data{std::move(other.data)} {
     75                  other.type = nullptr;
    5976        }
    6077
     
    6481                return *this;
    6582        }
     83
     84        EqvClass &EqvClass::operator=( EqvClass &&other ) {
     85                if ( this == &other ) return *this;
     86               
     87                vars = std::move(other.vars);
     88                type = other.type;
     89                allowWidening = std::move(other.allowWidening);
     90                data = std::move(other.data);
     91
     92                return *this;
     93        }
     94
     95        void EqvClass::set_type( Type* ty ) { type = ty; }
    6696
    6797        void EqvClass::print( std::ostream &os, Indenter indent ) const {
     
    81111        const EqvClass* TypeEnvironment::lookup( const std::string &var ) const {
    82112                for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    83                         if ( i->vars.find( var ) != i->vars.end() ) {
    84 ///       std::cout << var << " is in class ";
    85 ///       i->print( std::cout );
    86                                 return &*i;
    87                         }
    88 ///     std::cout << var << " is not in class ";
    89 ///     i->print( std::cout );
     113                        if ( i->vars.find( var ) != i->vars.end() ) return &*i;
    90114                } // for
    91115                return nullptr;
     
    105129        }
    106130
    107         void TypeEnvironment::add( const EqvClass &eqvClass ) {
    108                 filterOverlappingClasses( env, eqvClass );
    109                 env.push_back( eqvClass );
    110         }
    111 
    112131        void TypeEnvironment::add( EqvClass &&eqvClass ) {
    113132                filterOverlappingClasses( env, eqvClass );
     
    120139                        newClass.vars.insert( (*i)->get_name() );
    121140                        newClass.data = TypeDecl::Data{ (*i) };
    122                         env.push_back( newClass );
     141                        env.push_back( std::move(newClass) );
    123142                } // for
    124143        }
     
    134153                        // transition to TypeSubstitution
    135154                        newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false };
    136                         add( newClass );
     155                        add( std::move(newClass) );
    137156                }
    138157        }
     
    141160                for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    142161                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    143 ///       std::cerr << "adding " << *theVar;
    144162                                if ( theClass->type ) {
    145 ///         std::cerr << " bound to ";
    146 ///         theClass->type->print( std::cerr );
    147 ///         std::cerr << std::endl;
    148163                                        sub.add( *theVar, theClass->type );
    149164                                } else if ( theVar != theClass->vars.begin() ) {
    150165                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    151 ///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    152166                                        sub.add( *theVar, newTypeInst );
    153167                                } // if
    154168                        } // for
    155169                } // for
    156 ///   std::cerr << "input env is:" << std::endl;
    157 ///   print( std::cerr, 8 );
    158 ///   std::cerr << "sub is:" << std::endl;
    159 ///   sub.print( std::cerr, 8 );
    160170                sub.normalize();
    161171        }
    162172
    163173        void TypeEnvironment::print( std::ostream &os, Indenter indent ) const {
    164                 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    165                         i->print( os, indent );
     174                for ( const EqvClass & theClass : env ) {
     175                        theClass.print( os, indent );
    166176                } // for
    167177        }
     
    169179        std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) {
    170180                for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
    171                         if ( i->vars.find( var ) == i->vars.end() ) {
    172                                 return i;
    173                         } // if
     181                        if ( i->vars.count( var ) ) return i;
    174182                } // for
    175183                return env.end();
     
    178186        void TypeEnvironment::simpleCombine( const TypeEnvironment &second ) {
    179187                env.insert( env.end(), second.env.begin(), second.env.end() );
    180         }
    181 
    182         void TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ) {
    183                 TypeEnvironment secondCopy( second );
    184                 for ( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
    185                         EqvClass &newClass = *firstClass;
    186                         std::set< std::string > newVars;
    187                         for ( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
    188                                 std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
    189                                 if ( secondClass != secondCopy.env.end() ) {
    190                                         newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
    191                                         if ( secondClass->type ) {
    192                                                 if ( newClass.type ) {
    193                                                         newClass.type = combineFunc( newClass.type, secondClass->type );
    194                                                         newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
    195                                                 } else {
    196                                                         newClass.type = secondClass->type->clone();
    197                                                         newClass.allowWidening = secondClass->allowWidening;
    198                                                 } // if
    199                                         } // if
    200                                         secondCopy.env.erase( secondClass );
    201                                 } // if
    202                         } // for
    203                         newClass.vars.insert( newVars.begin(), newVars.end() );
    204                 } // for
    205                 for ( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
    206                         env.push_back( *secondClass );
    207                 } // for
    208188        }
    209189
     
    227207        }
    228208
     209        bool isFtype( Type *type ) {
     210                if ( dynamic_cast< FunctionType* >( type ) ) {
     211                        return true;
     212                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
     213                        return typeInst->get_isFtype();
     214                } // if
     215                return false;
     216        }
     217
     218        bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
     219                switch ( data.kind ) {
     220                  case TypeDecl::Dtype:
     221                        // to bind to an object type variable, the type must not be a function type.
     222                        // if the type variable is specified to be a complete type then the incoming
     223                        // type must also be complete
     224                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
     225                        return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
     226                  case TypeDecl::Ftype:
     227                        return isFtype( type );
     228                  case TypeDecl::Ttype:
     229                        // ttype unifies with any tuple type
     230                        return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
     231                } // switch
     232                return false;
     233        }
     234
     235        bool TypeEnvironment::bindVar( TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     236               
     237                // remove references from other, so that type variables can only bind to value types
     238                bindTo = bindTo->stripReferences();
     239                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
     240                assert( tyvar != openVars.end() );
     241                if ( ! tyVarCompatible( tyvar->second, bindTo ) ) {
     242                        return false;
     243                } // if
     244                if ( occurs( bindTo, typeInst->get_name(), *this ) ) {
     245                        return false;
     246                } // if
     247                auto curClass = internal_lookup( typeInst->get_name() );
     248                if ( curClass != env.end() ) {
     249                        if ( curClass->type ) {
     250                                Type *common = 0;
     251                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
     252                                Type *newType = curClass->type->clone();
     253                                newType->get_qualifiers() = typeInst->get_qualifiers();
     254                                if ( unifyInexact( newType, bindTo, *this, need, have, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
     255                                        if ( common ) {
     256                                                common->get_qualifiers() = Type::Qualifiers{};
     257                                                curClass->set_type( common );
     258                                        } // if
     259                                } else return false;
     260                        } else {
     261                                Type* newType = bindTo->clone();
     262                                newType->get_qualifiers() = Type::Qualifiers{};
     263                                curClass->set_type( newType );
     264                                curClass->allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     265                        } // if
     266                } else {
     267                        EqvClass newClass;
     268                        newClass.vars.insert( typeInst->get_name() );
     269                        newClass.type = bindTo->clone();
     270                        newClass.type->get_qualifiers() = Type::Qualifiers();
     271                        newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
     272                        newClass.data = data;
     273                        env.push_back( std::move(newClass) );
     274                } // if
     275                return true;
     276        }
     277
     278        bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     279
     280                auto class1 = internal_lookup( var1->get_name() );
     281                auto class2 = internal_lookup( var2->get_name() );
     282               
     283                // exit early if variables already bound together
     284                if ( class1 != env.end() && class1 == class2 ) {
     285                        class1->allowWidening &= widenMode;
     286                        return true;
     287                }
     288
     289                bool widen1 = false, widen2 = false;
     290                const Type *type1 = nullptr, *type2 = nullptr;
     291
     292                // check for existing bindings, perform occurs check
     293                if ( class1 != env.end() ) {
     294                        if ( class1->type ) {
     295                                if ( occurs( class1->type, var2->get_name(), *this ) ) return false;
     296                                type1 = class1->type;
     297                        } // if
     298                        widen1 = widenMode.widenFirst && class1->allowWidening;
     299                } // if
     300                if ( class2 != env.end() ) {
     301                        if ( class2->type ) {
     302                                if ( occurs( class2->type, var1->get_name(), *this ) ) return false;
     303                                type2 = class2->type;
     304                        } // if
     305                        widen2 = widenMode.widenSecond && class2->allowWidening;
     306                } // if
     307
     308                if ( type1 && type2 ) {
     309                        // both classes bound, merge if bound types can be unified
     310                        Type *newType1 = type1->clone(), *newType2 = type2->clone();
     311                        WidenMode newWidenMode{ widen1, widen2 };
     312                        Type *common = 0;
     313                        if ( unifyInexact( newType1, newType2, *this, need, have, openVars, newWidenMode, indexer, common ) ) {
     314                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
     315                                class1->allowWidening = widen1 && widen2;
     316                                if ( common ) {
     317                                        common->get_qualifiers() = Type::Qualifiers{};
     318                                        class1->set_type( common );
     319                                }
     320                                env.erase( class2 );
     321                        } else return false;
     322                } else if ( class1 != env.end() && class2 != env.end() ) {
     323                        // both classes exist, at least one unbound, merge unconditionally
     324                        if ( type1 ) {
     325                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
     326                                class1->allowWidening = widen1;
     327                                env.erase( class2 );
     328                        } else {
     329                                class2->vars.insert( class1->vars.begin(), class1->vars.end() );
     330                                class2->allowWidening = widen2;
     331                                env.erase( class1 );
     332                        } // if
     333                } else if ( class1 != env.end() ) {
     334                        // var2 unbound, add to class1
     335                        class1->vars.insert( var2->get_name() );
     336                        class1->allowWidening = widen1;
     337                } else if ( class2 != env.end() ) {
     338                        // var1 unbound, add to class2
     339                        class2->vars.insert( var1->get_name() );
     340                        class2->allowWidening = widen2;
     341                } else {
     342                        // neither var bound, create new class
     343                        EqvClass newClass;
     344                        newClass.vars.insert( var1->get_name() );
     345                        newClass.vars.insert( var2->get_name() );
     346                        newClass.allowWidening = widen1 && widen2;
     347                        newClass.data = data;
     348                        env.push_back( std::move(newClass) );
     349                } // if
     350                return true;
     351        }
     352
     353        void TypeEnvironment::forbidWidening() {
     354                for ( EqvClass& c : env ) c.allowWidening = false;
     355        }
     356
    229357        std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) {
    230358                env.print( out );
  • src/ResolvExpr/TypeEnvironment.h

    r0182bfa r28f3a19  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:24:58 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:35:45 2017
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    2121#include <set>                         // for set
    2222#include <string>                      // for string
     23#include <utility>                     // for move, swap
     24
     25#include "WidenMode.h"                 // for WidenMode
    2326
    2427#include "SynTree/Declaration.h"       // for TypeDecl::Data, DeclarationWit...
     
    7780
    7881                void initialize( const EqvClass &src, EqvClass &dest );
     82                void initialize( const EqvClass &src, EqvClass &dest, const Type *ty );
    7983                EqvClass();
    8084                EqvClass( const EqvClass &other );
     85                EqvClass( const EqvClass &other, const Type *ty );
     86                EqvClass( EqvClass &&other );
    8187                EqvClass &operator=( const EqvClass &other );
     88                EqvClass &operator=( EqvClass &&other );
    8289                void print( std::ostream &os, Indenter indent = {} ) const;
     90
     91                /// Takes ownership of `ty`, freeing old `type`
     92                void set_type(Type* ty);
    8393        };
    8494
     
    8696          public:
    8797                const EqvClass* lookup( const std::string &var ) const;
    88                 void add( const EqvClass &eqvClass );
     98          private:
    8999                void add( EqvClass &&eqvClass  );
     100          public:
    90101                void add( const Type::ForallList &tyDecls );
    91102                void add( const TypeSubstitution & sub );
     
    95106                bool isEmpty() const { return env.empty(); }
    96107                void print( std::ostream &os, Indenter indent = {} ) const;
    97                 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
     108                // void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
    98109                void simpleCombine( const TypeEnvironment &second );
    99110                void extractOpenVars( OpenVarSet &openVars ) const;
     
    104115                void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars );
    105116
    106                 typedef std::list< EqvClass >::iterator iterator;
    107                 iterator begin() { return env.begin(); }
    108                 iterator end() { return env.end(); }
    109                 typedef std::list< EqvClass >::const_iterator const_iterator;
    110                 const_iterator begin() const { return env.begin(); }
    111                 const_iterator end() const { return env.end(); }
     117                /// Binds the type class represented by `typeInst` to the type `bindTo`; will add
     118                /// the class if needed. Returns false on failure.
     119                bool bindVar( TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     120               
     121                /// Binds the type classes represented by `var1` and `var2` together; will add
     122                /// one or both classes if needed. Returns false on failure.
     123                bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     124
     125                /// Disallows widening for all bindings in the environment
     126                void forbidWidening();
     127
     128                using iterator = std::list< EqvClass >::const_iterator;
     129                iterator begin() const { return env.begin(); }
     130                iterator end() const { return env.end(); }
     131
    112132          private:
    113133                std::list< EqvClass > env;
     134               
    114135                std::list< EqvClass >::iterator internal_lookup( const std::string &var );
    115136        };
  • src/ResolvExpr/Unify.cc

    r0182bfa r28f3a19  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 16:22:54 2017
    13 // Update Count     : 42
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 43
    1414//
    1515
     
    122122        }
    123123
    124         bool isFtype( Type *type ) {
    125                 if ( dynamic_cast< FunctionType* >( type ) ) {
    126                         return true;
    127                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    128                         return typeInst->get_isFtype();
    129                 } // if
    130                 return false;
    131         }
    132 
    133         bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    134                 switch ( data.kind ) {
    135                   case TypeDecl::Dtype:
    136                         // to bind to an object type variable, the type must not be a function type.
    137                         // if the type variable is specified to be a complete type then the incoming
    138                         // type must also be complete
    139                         // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    140                         return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
    141                   case TypeDecl::Ftype:
    142                         return isFtype( type );
    143                   case TypeDecl::Ttype:
    144                         // ttype unifies with any tuple type
    145                         return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
    146                 } // switch
    147                 return false;
    148         }
    149 
    150         bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    151                 // remove references from other, so that type variables can only bind to value types
    152                 other = other->stripReferences();
    153                 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    154                 assert( tyvar != openVars.end() );
    155                 if ( ! tyVarCompatible( tyvar->second, other ) ) {
    156                         return false;
    157                 } // if
    158                 if ( occurs( other, typeInst->get_name(), env ) ) {
    159                         return false;
    160                 } // if
    161                 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
    162                         if ( curClass->type ) {
    163                                 Type *common = 0;
    164                                 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    165                                 Type* newType = curClass->type->clone();
    166                                 newType->get_qualifiers() = typeInst->get_qualifiers();
    167                                 if ( unifyInexact( newType, other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
    168                                         if ( common ) {
    169                                                 common->get_qualifiers() = Type::Qualifiers();
    170                                                 EqvClass newClass = *curClass;
    171                                                 newClass.type = common;
    172                                                 env.add( std::move(newClass) );
    173                                         } // if
    174                                         return true;
    175                                 } else {
    176                                         return false;
    177                                 } // if
    178                         } else {
    179                                 EqvClass newClass = *curClass;
    180                                 newClass.type = other->clone();
    181                                 newClass.type->get_qualifiers() = Type::Qualifiers();
    182                                 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    183                                 env.add( std::move(newClass) );
    184                         } // if
    185                 } else {
    186                         EqvClass newClass;
    187                         newClass.vars.insert( typeInst->get_name() );
    188                         newClass.type = other->clone();
    189                         newClass.type->get_qualifiers() = Type::Qualifiers();
    190                         newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    191                         newClass.data = data;
    192                         env.add( newClass );
    193                 } // if
    194                 return true;
    195         }
    196 
    197         bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    198                 bool result = true;
    199                 const EqvClass *class1 = env.lookup( var1->get_name() );
    200                 const EqvClass *class2 = env.lookup( var2->get_name() );
    201                 bool widen1 = false, widen2 = false;
    202                 Type *type1 = nullptr, *type2 = nullptr;
    203 
    204                 if ( class1 ) {
    205                         if ( class1->type ) {
    206                                 if ( occurs( class1->type, var2->get_name(), env ) ) {
    207                                         return false;
    208                                 } // if
    209                                 type1 = class1->type->clone();
    210                         } // if
    211                         widen1 = widenMode.widenFirst && class1->allowWidening;
    212                 } // if
    213                 if ( class2 ) {
    214                         if ( class2->type ) {
    215                                 if ( occurs( class2->type, var1->get_name(), env ) ) {
    216                                         return false;
    217                                 } // if
    218                                 type2 = class2->type->clone();
    219                         } // if
    220                         widen2 = widenMode.widenSecond && class2->allowWidening;
    221                 } // if
    222 
    223                 if ( type1 && type2 ) {
    224 //    std::cerr << "has type1 && type2" << std::endl;
    225                         WidenMode newWidenMode ( widen1, widen2 );
    226                         Type *common = 0;
    227                         if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    228                                 EqvClass newClass1 = *class1;
    229                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    230                                 newClass1.allowWidening = widen1 && widen2;
    231                                 if ( common ) {
    232                                         common->get_qualifiers() = Type::Qualifiers();
    233                                         newClass1.type = common;
    234                                 } // if
    235                                 env.add( std::move(newClass1) );
    236                         } else {
    237                                 result = false;
    238                         } // if
    239                 } else if ( class1 && class2 ) {
    240                         if ( type1 ) {
    241                                 EqvClass newClass1 = *class1;
    242                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    243                                 newClass1.allowWidening = widen1;
    244                                 env.add( std::move(newClass1) );
    245                         } else {
    246                                 EqvClass newClass2 = *class2;
    247                                 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
    248                                 newClass2.allowWidening = widen2;
    249                                 env.add( std::move(newClass2) );
    250                         } // if
    251                 } else if ( class1 ) {
    252                         EqvClass newClass1 = *class1;
    253                         newClass1.vars.insert( var2->get_name() );
    254                         newClass1.allowWidening = widen1;
    255                         env.add( std::move(newClass1) );
    256                 } else if ( class2 ) {
    257                         EqvClass newClass2 = *class2;
    258                         newClass2.vars.insert( var1->get_name() );
    259                         newClass2.allowWidening = widen2;
    260                         env.add( std::move(newClass2) );
    261                 } else {
    262                         EqvClass newClass;
    263                         newClass.vars.insert( var1->get_name() );
    264                         newClass.vars.insert( var2->get_name() );
    265                         newClass.allowWidening = widen1 && widen2;
    266                         newClass.data = data;
    267                         env.add( newClass );
    268                 } // if
    269                 return result;
    270         }
    271 
    272124        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
    273125                OpenVarSet closedVars;
     
    307159
    308160                if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
    309                         result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     161                        result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
    310162                } else if ( isopen1 ) {
    311                         result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     163                        result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
    312164                } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped?
    313                         result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     165                        result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
    314166                } else {
    315167                        PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
  • src/ResolvExpr/Unify.h

    r0182bfa r28f3a19  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 13:09:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 23:09:34 2017
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    2121#include "SynTree/Declaration.h"  // for TypeDecl, TypeDecl::Data
    2222#include "TypeEnvironment.h"      // for AssertionSet, OpenVarSet
     23#include "WidenMode.h"            // for WidenMode
    2324
    2425class Type;
     
    2930
    3031namespace ResolvExpr {
    31         struct WidenMode {
    32                 WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
    33                 WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
    34                 WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
    35                 WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
    36                 WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
    37                 operator bool() { return widenFirst && widenSecond; }
    38 
    39                 bool widenFirst : 1, widenSecond : 1;
    40         };
    41 
    42         bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    4332        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    4433        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
    4534        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     35        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    4636
    4737        template< typename Iterator1, typename Iterator2 >
  • src/SymTab/Indexer.cc

    r0182bfa r28f3a19  
    106106                if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
    107107
    108                 // helpful data structure
     108                // helpful data structure to organize properties for a type
    109109                struct ValueType {
    110                         struct DeclBall {
     110                        struct DeclBall { // properties for this particular decl
    111111                                IdData decl;
    112                                 bool isUserDefinedFunc; // properties for this particular decl
    113                                 bool isDefaultCtor;
    114                                 bool isDtor;
     112                                bool isUserDefinedFunc;
    115113                                bool isCopyFunc;
    116114                        };
    117115                        // properties for this type
    118                         bool existsUserDefinedFunc = false;    // any user-defined function found
    119                         bool existsUserDefinedCtor = false;    // any user-defined constructor found
    120                         bool existsUserDefinedDtor = false;    // any user-defined destructor found
    121116                        bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
    122                         bool existsUserDefinedDefaultCtor = false; // user-defined default ctor found
     117                        BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
    123118                        std::list< DeclBall > decls;
    124119
     
    127122                        ValueType & operator+=( IdData data ) {
    128123                                DeclarationWithType * function = data.id;
    129                                 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
    130                                 bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
    131                                 bool isDtor = InitTweak::isDestructor( function );
    132                                 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
    133                                 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
    134                                 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
    135                                 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
    136                                 existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor);
     124                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
     125                                bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
     126                                decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
    137127                                existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
    138                                 existsUserDefinedDefaultCtor = existsUserDefinedDefaultCtor || (isUserDefinedFunc && isDefaultCtor);
     128                                if ( isUserDefinedFunc && ! deleteStmt ) {
     129                                        // any user-defined function can act as an implicit delete statement for generated constructors.
     130                                        // a delete stmt should not act as an implicit delete statement.
     131                                        deleteStmt = data.id;
     132                                }
    139133                                return *this;
    140134                        }
     
    148142                for ( auto decl : copy ) {
    149143                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
    150                                 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
     144                                std::list< DeclarationWithType * > & params = function->type->parameters;
    151145                                assert( ! params.empty() );
    152146                                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     
    160154
    161155                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
    162                 // the set of ctor/dtor/assign that are seen by the requester. In particular, if the user defines
    163                 // a default ctor, then the generated default ctor should never be seen, likewise for copy ctor
    164                 // and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen.
    165                 // If the user defines any ctor then the generated default ctor should not be seen (intrinsic default
    166                 // ctor must be overridden exactly).
     156                // the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
     157                // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
     158                // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
     159                // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
     160                // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
     161                // then the generated copy constructor is unavailable, and likewise for the assignment operator.
    167162                for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
    168163                        ValueType & val = pair.second;
    169164                        for ( ValueType::DeclBall ball : val.decls ) {
    170                                 bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    171                                 bool isUserDefinedFunc = ball.isUserDefinedFunc;
    172                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    173                                 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    174                                 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
    175                                 if ( noUserDefinedFunc || isUserDefinedFunc || isAcceptableDefaultCtor || isAcceptableCopyFunc || isAcceptableDtor ) {
    176                                         // decl conforms to the rules described above, so it should be seen by the requester
    177                                         out.push_back( ball.decl );
     165                                bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
     166                                bool isCopyFunc = ball.isCopyFunc;
     167                                bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
     168
     169                                // only implicitly delete non-user defined functions that are not intrinsic, and are
     170                                // not copy functions (assignment or copy constructor). If a  user-defined copy function exists,
     171                                // do not pass along the non-user-defined copy functions since signatures do not have to match,
     172                                // and the generated functions will often be cheaper.
     173                                if ( isNotUserDefinedFunc ) {
     174                                        if ( isCopyFunc ) {
     175                                                // Skip over non-user-defined copy functions when there is a user-defined copy function.
     176                                                // Since their signatures do not have to be exact, deleting them is the wrong choice.
     177                                                if ( existsUserDefinedCopyFunc ) continue;
     178                                        } else {
     179                                                // delete non-user-defined non-copy functions if applicable.
     180                                                // deleteStmt will be non-null only if a user-defined function is found.
     181                                                ball.decl.deleteStmt = val.deleteStmt;
     182                                        }
    178183                                }
     184                                out.push_back( ball.decl );
    179185                        }
    180186                }
     
    471477        void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
    472478                // default handling of conflicts is to raise an error
    473                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr );
     479                addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
    474480        }
    475481
  • src/SymTab/Mangler.cc

    r0182bfa r28f3a19  
    171171                                        "w",    // SignedInt128
    172172                                        "Uw",   // UnsignedInt128
     173                                        "x",   // Float80
     174                                        "y",   // Float128
    173175                                };
     176                                static_assert(
     177                                        sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
     178                                        "Each basic type kind should have a corresponding mangler letter"
     179                                );
    174180
    175181                                printQualifiers( basicType );
     182                                assert( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]) );
    176183                                mangleName << btLetter[ basicType->get_kind() ];
    177184                        }
     
    218225                                GuardValue( inFunctionType );
    219226                                inFunctionType = true;
    220                                 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
     227                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
    221228                                acceptAll( returnTypes, *visitor );
    222229                                mangleName << "_";
    223                                 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
     230                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
    224231                                acceptAll( paramTypes, *visitor );
    225232                                mangleName << "_";
     
    229236                                printQualifiers( refType );
    230237
    231                                 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
     238                                mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
    232239
    233240                                if ( mangleGenericParams ) {
    234                                         std::list< Expression* >& params = refType->get_parameters();
     241                                        std::list< Expression* >& params = refType->parameters;
    235242                                        if ( ! params.empty() ) {
    236243                                                mangleName << "_";
    237244                                                for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
    238245                                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    239                                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
    240                                                         maybeAccept( paramType->get_type(), *visitor );
     246                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
     247                                                        maybeAccept( paramType->type, *visitor );
    241248                                                }
    242249                                                mangleName << "_";
  • src/SymTab/Validate.cc

    r0182bfa r28f3a19  
    4949#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
    5050#include "Common/GC.h"                 // for new_static_root, register_static_root
     51#include "ControlStruct/Mutate.h"      // for ForExprMutator
    5152#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    5253#include "Common/ScopedMap.h"          // for ScopedMap
     
    7778class SwitchStmt;
    7879
    79 
    8080#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
    8181
     
    275275                Concurrency::applyKeywords( translationUnit );
    276276                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     277                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    277278                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    278279                Concurrency::implementMutexFuncs( translationUnit );
  • src/SynTree/BasicType.cc

    r0182bfa r28f3a19  
    5555          case DoubleImaginary:
    5656          case LongDoubleImaginary:
     57          case Float80:
     58          case Float128:
    5759                return false;
    5860          case NUMBER_OF_BASIC_TYPES:
  • src/SynTree/Declaration.cc

    r0182bfa r28f3a19  
    9292}
    9393
     94
    9495// Local Variables: //
    9596// tab-width: 4 //
  • src/SynTree/Declaration.h

    r0182bfa r28f3a19  
    8383        Expression *asmName;
    8484        std::list< Attribute * > attributes;
     85        bool isDeleted = false;
    8586
    8687        DeclarationWithType( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage, const std::list< Attribute * > & attributes, Type::FuncSpecifiers fs );
  • src/SynTree/Expression.cc

    r0182bfa r28f3a19  
    640640
    641641
     642DefaultArgExpr::DefaultArgExpr( Expression * expr ) : expr( expr ) {
     643        assert( expr->result );
     644        result = expr->result->clone();
     645}
     646DefaultArgExpr::DefaultArgExpr( const DefaultArgExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ) {}
     647
     648void DefaultArgExpr::print( std::ostream & os, Indenter indent ) const {
     649        os << "Default Argument Expression" << std::endl << indent+1;
     650        expr->print( os, indent+1 );
     651}
     652
     653GenericExpr::Association::Association( Type * type, Expression * expr ) : type( type ), expr( expr ), isDefault( false ) {}
     654GenericExpr::Association::Association( Expression * expr ) : type( nullptr ), expr( expr ), isDefault( true ) {}
     655GenericExpr::Association::Association( const Association & other ) : type( maybeClone( other.type ) ), expr( maybeClone( other.expr ) ), isDefault( other.isDefault ) {}
     656
     657GenericExpr::GenericExpr( Expression * control, const std::list<Association> & assoc ) : Expression(), control( control ), associations( assoc ) {}
     658GenericExpr::GenericExpr( const GenericExpr & other ) : Expression(other), control( maybeClone( other.control ) ), associations( other.associations ) {}
     659GenericExpr::~GenericExpr() {}
     660
     661void GenericExpr::print( std::ostream & os, Indenter indent ) const {
     662        os << "C11 _Generic Expression" << std::endl << indent+1;
     663        control->print( os, indent+1 );
     664        os << std::endl << indent+1 << "... with associations: " << std::endl;
     665        for ( const Association & assoc : associations ) {
     666                os << indent+1;
     667                if (assoc.isDefault) {
     668                        os << "... default: ";
     669                        assoc.expr->print( os, indent+1 );
     670                } else {
     671                        os << "... type: ";
     672                        assoc.type->print( os, indent+1 );
     673                        os << std::endl << indent+1 << "... expression: ";
     674                        assoc.expr->print( os, indent+1 );
     675                        os << std::endl;
     676                }
     677                os << std::endl;
     678        }
     679}
     680
    642681// Local Variables: //
    643682// tab-width: 4 //
  • src/SynTree/Expression.h

    r0182bfa r28f3a19  
    833833};
    834834
     835/// expression wrapping the use of a default argument - should never make it past the resolver.
     836class DefaultArgExpr : public Expression {
     837public:
     838        Expression * expr;
     839
     840        DefaultArgExpr( Expression * expr );
     841        DefaultArgExpr( const DefaultArgExpr & other );
     842
     843        virtual DefaultArgExpr * clone() const { return new DefaultArgExpr( * this ); }
     844        virtual void accept( Visitor & v ) { v.visit( this ); }
     845        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     846        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     847};
     848
     849/// C11 _Generic expression
     850class GenericExpr : public Expression {
     851public:
     852        struct Association {
     853                Type * type = nullptr;
     854                Expression * expr = nullptr;
     855                bool isDefault = false;
     856
     857                Association( Type * type, Expression * expr );
     858                Association( Expression * expr );
     859                Association( const Association & other );
     860                Association & operator=( const Association & other ) = delete; // at the moment this isn't used, and I don't want to implement it
     861        };
     862
     863        Expression * control;
     864        std::list<Association> associations;
     865
     866        GenericExpr( Expression * control, const std::list<Association> & assoc );
     867        GenericExpr( const GenericExpr & other );
     868        ~GenericExpr();
     869
     870        virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
     871        virtual void accept( Visitor & v ) { v.visit( this ); }
     872        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     873        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     874};
     875
    835876// Local Variables: //
    836877// tab-width: 4 //
  • src/SynTree/Mutator.h

    r0182bfa r28f3a19  
    9393        virtual Expression * mutate( InitExpr  * initExpr ) = 0;
    9494        virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
     95        virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0;
     96        virtual Expression * mutate( GenericExpr * genExpr ) = 0;
    9597
    9698        virtual Type * mutate( VoidType * basicType ) = 0;
  • src/SynTree/ReferenceToType.cc

    r0182bfa r28f3a19  
    4646
    4747namespace {
    48         void doLookup( const std::list< Declaration* > &members, const std::string &name, std::list< Declaration* > &foundDecls ) {
    49                 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    50                         if ( (*i)->get_name() == name ) {
    51                                 foundDecls.push_back( *i );
     48        void doLookup( const std::list< Declaration * > & members, const std::string & name, std::list< Declaration* > & foundDecls ) {
     49                for ( Declaration * decl : members ) {
     50                        if ( decl->name == name ) {
     51                                foundDecls.push_back( decl );
    5252                        } // if
    5353                } // for
     
    5656
    5757StructInstType::StructInstType( const Type::Qualifiers & tq, StructDecl * baseStruct, const std::list< Attribute * > & attributes ) :
    58                 Parent( tq, baseStruct->get_name(), attributes ), baseStruct( baseStruct ) {}
     58                Parent( tq, baseStruct->name, attributes ), baseStruct( baseStruct ) {}
    5959
    6060std::string StructInstType::typeString() const { return "struct"; }
     
    8080void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    8181        assert( baseStruct );
    82         doLookup( baseStruct->get_members(), name, foundDecls );
     82        doLookup( baseStruct->members, name, foundDecls );
    8383}
    8484
     
    9999
    100100UnionInstType::UnionInstType( const Type::Qualifiers & tq, UnionDecl * baseUnion, const std::list< Attribute * > & attributes ) :
    101                 Parent( tq, baseUnion->get_name(), attributes ), baseUnion( baseUnion ) {}
     101                Parent( tq, baseUnion->name, attributes ), baseUnion( baseUnion ) {}
    102102
    103103std::string UnionInstType::typeString() const { return "union"; }
     
    123123void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    124124        assert( baseUnion );
    125         doLookup( baseUnion->get_members(), name, foundDecls );
     125        doLookup( baseUnion->members, name, foundDecls );
    126126}
    127127
  • src/SynTree/Statement.cc

    r0182bfa r28f3a19  
    208208}
    209209
    210 WhileStmt::WhileStmt( Expression *condition, Statement *body, bool isDoWhile ):
    211         Statement(), condition( condition), body( body), isDoWhile( isDoWhile) {
     210WhileStmt::WhileStmt( Expression *condition, Statement *body, std::list< Statement * > & initialization, bool isDoWhile ):
     211        Statement(), condition( condition), body( body), initialization( initialization ), isDoWhile( isDoWhile) {
    212212}
    213213
  • src/SynTree/Statement.h

    r0182bfa r28f3a19  
    213213        Expression *condition;
    214214        Statement *body;
     215        std::list<Statement *> initialization;
    215216        bool isDoWhile;
    216217
    217218        WhileStmt( Expression *condition,
    218                Statement *body, bool isDoWhile = false );
     219               Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
    219220        WhileStmt( const WhileStmt &other );
    220221
  • src/SynTree/SynTree.h

    r0182bfa r28f3a19  
    101101class InitExpr;
    102102class DeletedExpr;
     103class DefaultArgExpr;
     104class GenericExpr;
    103105
    104106class Type;
  • src/SynTree/Type.cc

    r0182bfa r28f3a19  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:16:32 2017
    13 // Update Count     : 38
     12// Last Modified On : Fri Jun 22 10:17:19 2018
     13// Update Count     : 39
    1414//
    1515#include "Type.h"
     
    2424using namespace std;
    2525
    26 const char *BasicType::typeNames[BasicType::NUMBER_OF_BASIC_TYPES] = {
     26const char *BasicType::typeNames[] = {
    2727        "_Bool",
    2828        "char",
     
    4848        "__int128",
    4949        "unsigned __int128",
     50        "__float80",
     51        "__float128"
    5052};
     53static_assert(
     54        sizeof(BasicType::typeNames)/sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
     55        "Each basic type name should have a corresponding kind enum value"
     56);
    5157
    5258Type::Type( const Qualifiers &tq, const std::list< Attribute * > & attributes ) : tq( tq ), attributes( attributes ) {}
     
    5864
    5965// These must remain in the same order as the corresponding bit fields.
    60 const char * Type::FuncSpecifiersNames[] = { "inline", "fortran", "_Noreturn" };
     66const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
    6167const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
    6268const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
  • src/SynTree/Type.h

    r0182bfa r28f3a19  
    230230                SignedInt128,
    231231                UnsignedInt128,
     232                Float80,
     233                Float128,
    232234                NUMBER_OF_BASIC_TYPES
    233235        } kind;
  • src/SynTree/Visitor.h

    r0182bfa r28f3a19  
    9595        virtual void visit( InitExpr *  initExpr ) = 0;
    9696        virtual void visit( DeletedExpr * delExpr ) = 0;
     97        virtual void visit( DefaultArgExpr * argExpr ) = 0;
     98        virtual void visit( GenericExpr * genExpr ) = 0;
    9799
    98100        virtual void visit( VoidType * basicType ) = 0;
  • src/benchmark/Makefile.am

    r0182bfa r28f3a19  
    9292
    9393## =========================================================================================================
     94loop$(EXEEXT):
     95        @@BACKEND_CC@ loop.c      -DBENCH_N=5000000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     96
     97function$(EXEEXT):
     98        @@BACKEND_CC@ function.c  -DBENCH_N=5000000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     99
     100fetch_add$(EXEEXT):
     101        @@BACKEND_CC@ fetch_add.c -DBENCH_N=500000000  -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     102
     103## =========================================================================================================
    94104ctxswitch$(EXEEXT): \
     105        loop.run                                \
     106        function.run                    \
     107        fetch_add.run                   \
    95108        ctxswitch-pthread.run           \
    96109        ctxswitch-cfa_coroutine.run     \
    97110        ctxswitch-cfa_thread.run        \
     111        ctxswitch-cfa_thread2.run       \
    98112        ctxswitch-upp_coroutine.run     \
    99113        ctxswitch-upp_thread.run        \
     114        -ctxswitch-kos_fibre.run        \
     115        -ctxswitch-kos_fibre2.run       \
    100116        ctxswitch-goroutine.run         \
    101117        ctxswitch-java_thread.run
    102118
     119ctxswitch-pthread$(EXEEXT):
     120        @@BACKEND_CC@ ctxswitch/pthreads.c     -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     121
    103122ctxswitch-cfa_coroutine$(EXEEXT):
    104         @${CC}        ctxswitch/cfa_cor.c   -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     123        @${CC}        ctxswitch/cfa_cor.c      -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    105124
    106125ctxswitch-cfa_thread$(EXEEXT):
    107         @${CC}        ctxswitch/cfa_thrd.c  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     126        @${CC}        ctxswitch/cfa_thrd.c     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     127
     128ctxswitch-cfa_thread2$(EXEEXT):
     129        @${CC}        ctxswitch/cfa_thrd2.c    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    108130
    109131ctxswitch-upp_coroutine$(EXEEXT):
    110         @u++          ctxswitch/upp_cor.cc  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     132        @u++          ctxswitch/upp_cor.cc     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    111133
    112134ctxswitch-upp_thread$(EXEEXT):
    113         @u++          ctxswitch/upp_thrd.cc -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    114 
    115 ctxswitch-pthread$(EXEEXT):
    116         @@BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     135        @u++          ctxswitch/upp_thrd.cc    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     136
     137ctxswitch-kos_fibre$(EXEEXT):
     138        @${CXX}       ctxswitch/kos_fibre.cpp  -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
     139
     140ctxswitch-kos_fibre2$(EXEEXT):
     141        @${CXX}       ctxswitch/kos_fibre2.cpp -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
    117142
    118143ctxswitch-goroutine$(EXEEXT):
     
    127152## =========================================================================================================
    128153mutex$(EXEEXT) :\
    129         mutex-function.run      \
    130         mutex-fetch_add.run     \
     154        loop.run                        \
     155        function.run            \
     156        fetch_add.run           \
    131157        mutex-pthread_lock.run  \
    132158        mutex-upp.run           \
     
    135161        mutex-cfa4.run          \
    136162        mutex-java_thread.run
    137 
    138 mutex-function$(EXEEXT):
    139         @@BACKEND_CC@ mutex/function.c    -DBENCH_N=500000000   -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    140 
    141 mutex-fetch_add$(EXEEXT):
    142         @@BACKEND_CC@ mutex/fetch_add.c   -DBENCH_N=500000000   -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    143163
    144164mutex-pthread_lock$(EXEEXT):
     
    277297
    278298compile-io$(EXEEXT):
    279         @${CC} -quiet -fsyntax-only -w ../tests/io.c                                    @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     299        @${CC} -quiet -fsyntax-only -w ../tests/io1.c                           @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    280300
    281301compile-monitor$(EXEEXT):
    282         @${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c            @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     302        @${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c    @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    283303
    284304compile-operators$(EXEEXT):
     
    289309
    290310compile-typeof$(EXEEXT):
    291         @${CC} -quiet -fsyntax-only -w ../tests/typeof.c                                @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    292 
     311        @${CC} -quiet -fsyntax-only -w ../tests/typeof.c                        @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     312
  • src/benchmark/Makefile.in

    r0182bfa r28f3a19  
    505505        @echo "}"
    506506
     507loop$(EXEEXT):
     508        @@BACKEND_CC@ loop.c      -DBENCH_N=5000000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     509
     510function$(EXEEXT):
     511        @@BACKEND_CC@ function.c  -DBENCH_N=5000000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     512
     513fetch_add$(EXEEXT):
     514        @@BACKEND_CC@ fetch_add.c -DBENCH_N=500000000  -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     515
    507516ctxswitch$(EXEEXT): \
     517        loop.run                                \
     518        function.run                    \
     519        fetch_add.run                   \
    508520        ctxswitch-pthread.run           \
    509521        ctxswitch-cfa_coroutine.run     \
    510522        ctxswitch-cfa_thread.run        \
     523        ctxswitch-cfa_thread2.run       \
    511524        ctxswitch-upp_coroutine.run     \
    512525        ctxswitch-upp_thread.run        \
     526        -ctxswitch-kos_fibre.run        \
     527        -ctxswitch-kos_fibre2.run       \
    513528        ctxswitch-goroutine.run         \
    514529        ctxswitch-java_thread.run
    515530
     531ctxswitch-pthread$(EXEEXT):
     532        @@BACKEND_CC@ ctxswitch/pthreads.c     -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     533
    516534ctxswitch-cfa_coroutine$(EXEEXT):
    517         @${CC}        ctxswitch/cfa_cor.c   -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     535        @${CC}        ctxswitch/cfa_cor.c      -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    518536
    519537ctxswitch-cfa_thread$(EXEEXT):
    520         @${CC}        ctxswitch/cfa_thrd.c  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     538        @${CC}        ctxswitch/cfa_thrd.c     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     539
     540ctxswitch-cfa_thread2$(EXEEXT):
     541        @${CC}        ctxswitch/cfa_thrd2.c    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    521542
    522543ctxswitch-upp_coroutine$(EXEEXT):
    523         @u++          ctxswitch/upp_cor.cc  -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     544        @u++          ctxswitch/upp_cor.cc     -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    524545
    525546ctxswitch-upp_thread$(EXEEXT):
    526         @u++          ctxswitch/upp_thrd.cc -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    527 
    528 ctxswitch-pthread$(EXEEXT):
    529         @@BACKEND_CC@ ctxswitch/pthreads.c  -DBENCH_N=50000000  -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     547        @u++          ctxswitch/upp_thrd.cc    -DBENCH_N=50000000  -I. -nodebug -lrt -quiet             ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     548
     549ctxswitch-kos_fibre$(EXEEXT):
     550        @${CXX}       ctxswitch/kos_fibre.cpp  -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
     551
     552ctxswitch-kos_fibre2$(EXEEXT):
     553        @${CXX}       ctxswitch/kos_fibre2.cpp -DBENCH_N=50000000  -I. -I/home/tdelisle/software/KOS/src/ -g -O2 -lfibre -lpthread -lrt
    530554
    531555ctxswitch-goroutine$(EXEEXT):
     
    539563
    540564mutex$(EXEEXT) :\
    541         mutex-function.run      \
    542         mutex-fetch_add.run     \
     565        loop.run                        \
     566        function.run            \
     567        fetch_add.run           \
    543568        mutex-pthread_lock.run  \
    544569        mutex-upp.run           \
     
    547572        mutex-cfa4.run          \
    548573        mutex-java_thread.run
    549 
    550 mutex-function$(EXEEXT):
    551         @@BACKEND_CC@ mutex/function.c    -DBENCH_N=500000000   -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    552 
    553 mutex-fetch_add$(EXEEXT):
    554         @@BACKEND_CC@ mutex/fetch_add.c   -DBENCH_N=500000000   -I. -lrt -pthread                    ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    555574
    556575mutex-pthread_lock$(EXEEXT):
     
    682701
    683702compile-io$(EXEEXT):
    684         @${CC} -quiet -fsyntax-only -w ../tests/io.c                                    @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     703        @${CC} -quiet -fsyntax-only -w ../tests/io1.c                           @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    685704
    686705compile-monitor$(EXEEXT):
    687         @${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c            @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     706        @${CC} -quiet -fsyntax-only -w ../tests/concurrent/monitor.c    @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    688707
    689708compile-operators$(EXEEXT):
     
    694713
    695714compile-typeof$(EXEEXT):
    696         @${CC} -quiet -fsyntax-only -w ../tests/typeof.c                                @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
     715        @${CC} -quiet -fsyntax-only -w ../tests/typeof.c                        @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}
    697716
    698717# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • src/benchmark/function.c

    r0182bfa r28f3a19  
    44
    55void __attribute__((noinline)) do_call() {
    6         asm volatile ("");
     6        asm volatile("" ::: "memory");
    77}
    88
  • src/libcfa/Makefile.am

    r0182bfa r28f3a19  
    5151# not all platforms support concurrency, add option do disable it
    5252if BUILD_CONCURRENCY
    53 headers += concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor
     53headers += concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor concurrency/mutex
    5454endif
    5555
  • src/libcfa/Makefile.in

    r0182bfa r28f3a19  
    9797
    9898# not all platforms support concurrency, add option do disable it
    99 @BUILD_CONCURRENCY_TRUE@am__append_3 = concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor
     99@BUILD_CONCURRENCY_TRUE@am__append_3 = concurrency/coroutine concurrency/thread concurrency/kernel concurrency/monitor concurrency/mutex
    100100
    101101# not all platforms support concurrency, add option do disable it
     
    153153        containers/pair.c containers/result.c containers/vector.c \
    154154        concurrency/coroutine.c concurrency/thread.c \
    155         concurrency/kernel.c concurrency/monitor.c assert.c \
    156         exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
    157         concurrency/alarm.c concurrency/invoke.c \
    158         concurrency/preemption.c
     155        concurrency/kernel.c concurrency/monitor.c concurrency/mutex.c \
     156        assert.c exception.c virtual.c \
     157        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
     158        concurrency/invoke.c concurrency/preemption.c
    159159am__dirstamp = $(am__leading_dot)dirstamp
    160160@BUILD_CONCURRENCY_TRUE@am__objects_1 = concurrency/libcfa_d_a-coroutine.$(OBJEXT) \
    161161@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-thread.$(OBJEXT) \
    162162@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-kernel.$(OBJEXT) \
    163 @BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-monitor.$(OBJEXT)
     163@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-monitor.$(OBJEXT) \
     164@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_d_a-mutex.$(OBJEXT)
    164165am__objects_2 = libcfa_d_a-fstream.$(OBJEXT) \
    165166        libcfa_d_a-iostream.$(OBJEXT) libcfa_d_a-iterator.$(OBJEXT) \
     
    188189        containers/result.c containers/vector.c \
    189190        concurrency/coroutine.c concurrency/thread.c \
    190         concurrency/kernel.c concurrency/monitor.c assert.c \
    191         exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
    192         concurrency/alarm.c concurrency/invoke.c \
    193         concurrency/preemption.c
     191        concurrency/kernel.c concurrency/monitor.c concurrency/mutex.c \
     192        assert.c exception.c virtual.c \
     193        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
     194        concurrency/invoke.c concurrency/preemption.c
    194195@BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
    195196@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-thread.$(OBJEXT) \
    196197@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-kernel.$(OBJEXT) \
    197 @BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-monitor.$(OBJEXT)
     198@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-monitor.$(OBJEXT) \
     199@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-mutex.$(OBJEXT)
    198200am__objects_6 = libcfa_a-fstream.$(OBJEXT) libcfa_a-iostream.$(OBJEXT) \
    199201        libcfa_a-iterator.$(OBJEXT) libcfa_a-limits.$(OBJEXT) \
     
    264266        containers/result containers/vector concurrency/coroutine \
    265267        concurrency/thread concurrency/kernel concurrency/monitor \
    266         ${shell find stdhdr -type f -printf "%p "} math gmp time_t.h \
    267         clock bits/align.h bits/containers.h bits/defs.h bits/debug.h \
    268         bits/locks.h concurrency/invoke.h
     268        concurrency/mutex ${shell find stdhdr -type f -printf "%p "} \
     269        math gmp time_t.h clock bits/align.h bits/containers.h \
     270        bits/defs.h bits/debug.h bits/locks.h concurrency/invoke.h
    269271HEADERS = $(nobase_cfa_include_HEADERS)
    270272am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     
    548550concurrency/libcfa_d_a-monitor.$(OBJEXT): concurrency/$(am__dirstamp) \
    549551        concurrency/$(DEPDIR)/$(am__dirstamp)
     552concurrency/libcfa_d_a-mutex.$(OBJEXT): concurrency/$(am__dirstamp) \
     553        concurrency/$(DEPDIR)/$(am__dirstamp)
    550554concurrency/CtxSwitch-@MACHINE_TYPE@.$(OBJEXT):  \
    551555        concurrency/$(am__dirstamp) \
     
    580584        concurrency/$(DEPDIR)/$(am__dirstamp)
    581585concurrency/libcfa_a-monitor.$(OBJEXT): concurrency/$(am__dirstamp) \
     586        concurrency/$(DEPDIR)/$(am__dirstamp)
     587concurrency/libcfa_a-mutex.$(OBJEXT): concurrency/$(am__dirstamp) \
    582588        concurrency/$(DEPDIR)/$(am__dirstamp)
    583589concurrency/libcfa_a-alarm.$(OBJEXT): concurrency/$(am__dirstamp) \
     
    635641@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-kernel.Po@am__quote@
    636642@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-monitor.Po@am__quote@
     643@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-mutex.Po@am__quote@
    637644@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-preemption.Po@am__quote@
    638645@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_a-thread.Po@am__quote@
     
    642649@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-kernel.Po@am__quote@
    643650@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-monitor.Po@am__quote@
     651@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-mutex.Po@am__quote@
    644652@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-preemption.Po@am__quote@
    645653@AMDEP_TRUE@@am__include@ @am__quote@concurrency/$(DEPDIR)/libcfa_d_a-thread.Po@am__quote@
     
    930938@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
    931939
     940concurrency/libcfa_d_a-mutex.o: concurrency/mutex.c
     941@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-mutex.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo -c -o concurrency/libcfa_d_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     942@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_d_a-mutex.Po
     943@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_d_a-mutex.o' libtool=no @AMDEPBACKSLASH@
     944@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     945@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     946
     947concurrency/libcfa_d_a-mutex.obj: concurrency/mutex.c
     948@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_d_a-mutex.obj -MD -MP -MF concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo -c -o concurrency/libcfa_d_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
     949@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_d_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_d_a-mutex.Po
     950@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_d_a-mutex.obj' libtool=no @AMDEPBACKSLASH@
     951@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     952@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_d_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
     953
    932954libcfa_d_a-assert.o: assert.c
    933955@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-assert.o -MD -MP -MF $(DEPDIR)/libcfa_d_a-assert.Tpo -c -o libcfa_d_a-assert.o `test -f 'assert.c' || echo '$(srcdir)/'`assert.c
     
    12371259@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    12381260@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-monitor.obj `if test -f 'concurrency/monitor.c'; then $(CYGPATH_W) 'concurrency/monitor.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/monitor.c'; fi`
     1261
     1262concurrency/libcfa_a-mutex.o: concurrency/mutex.c
     1263@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_a-mutex.o -MD -MP -MF concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo -c -o concurrency/libcfa_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     1264@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_a-mutex.Po
     1265@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_a-mutex.o' libtool=no @AMDEPBACKSLASH@
     1266@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1267@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-mutex.o `test -f 'concurrency/mutex.c' || echo '$(srcdir)/'`concurrency/mutex.c
     1268
     1269concurrency/libcfa_a-mutex.obj: concurrency/mutex.c
     1270@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT concurrency/libcfa_a-mutex.obj -MD -MP -MF concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo -c -o concurrency/libcfa_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
     1271@am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) concurrency/$(DEPDIR)/libcfa_a-mutex.Tpo concurrency/$(DEPDIR)/libcfa_a-mutex.Po
     1272@AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='concurrency/mutex.c' object='concurrency/libcfa_a-mutex.obj' libtool=no @AMDEPBACKSLASH@
     1273@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1274@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o concurrency/libcfa_a-mutex.obj `if test -f 'concurrency/mutex.c'; then $(CYGPATH_W) 'concurrency/mutex.c'; else $(CYGPATH_W) '$(srcdir)/concurrency/mutex.c'; fi`
    12391275
    12401276libcfa_a-assert.o: assert.c
  • src/libcfa/bits/containers.h

    r0182bfa r28f3a19  
    183183                verify( *tail == NULL );
    184184                return val;
     185        }
     186
     187        forall(dtype T | is_node(T))
     188        static inline bool ?!=?( __queue(T) & this, zero_t zero ) {
     189                return this.head != 0;
    185190        }
    186191#endif
     
    261266                __get( node ).prev = NULL;
    262267        }
     268
     269        forall(dtype T | sized(T))
     270        static inline bool ?!=?( __dllist(T) & this, zero_t zero ) {
     271                return this.head != 0;
     272        }
    263273        #undef next
    264274        #undef prev
  • src/libcfa/bits/locks.h

    r0182bfa r28f3a19  
    1818#include "bits/debug.h"
    1919#include "bits/defs.h"
     20#include <assert.h>
     21
     22#ifdef __cforall
     23        extern "C" {
     24                #include <pthread.h>
     25        }
     26#endif
    2027
    2128// pause to prevent excess processor bus usage
     
    112119                __atomic_clear( &this.lock, __ATOMIC_RELEASE );
    113120        }
     121
     122
     123        #ifdef __CFA_WITH_VERIFY__
     124                extern bool __cfaabi_dbg_in_kernel();
     125        #endif
     126
     127        struct __bin_sem_t {
     128                bool                    signaled;
     129                pthread_mutex_t         lock;
     130                pthread_cond_t          cond;
     131        };
     132
     133        static inline void ?{}(__bin_sem_t & this) with( this ) {
     134                signaled = false;
     135                pthread_mutex_init(&lock, NULL);
     136                pthread_cond_init (&cond, NULL);
     137        }
     138
     139        static inline void ^?{}(__bin_sem_t & this) with( this ) {
     140                pthread_mutex_destroy(&lock);
     141                pthread_cond_destroy (&cond);
     142        }
     143
     144        static inline void wait(__bin_sem_t & this) with( this ) {
     145                verify(__cfaabi_dbg_in_kernel());
     146                pthread_mutex_lock(&lock);
     147                        if(!signaled) {   // this must be a loop, not if!
     148                                pthread_cond_wait(&cond, &lock);
     149                        }
     150                        signaled = false;
     151                pthread_mutex_unlock(&lock);
     152        }
     153
     154        static inline void post(__bin_sem_t & this) with( this ) {
     155                verify(__cfaabi_dbg_in_kernel());
     156
     157                pthread_mutex_lock(&lock);
     158                        bool needs_signal = !signaled;
     159                        signaled = true;
     160                pthread_mutex_unlock(&lock);
     161
     162                if (needs_signal)
     163                        pthread_cond_signal(&cond);
     164        }
    114165#endif
  • src/libcfa/concurrency/invoke.h

    r0182bfa r28f3a19  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 22:33:59 2018
    13 // Update Count     : 30
     12// Last Modified On : Sat May 19 08:23:21 2018
     13// Update Count     : 31
    1414//
    1515
     
    1818#include "bits/locks.h"
    1919
    20 #define TL_GET( member ) kernelTLS.member
    21 #define TL_SET( member, value ) kernelTLS.member = value;
    22 
    2320#ifdef __cforall
    2421extern "C" {
     
    2825#ifndef _INVOKE_H_
    2926#define _INVOKE_H_
     27
     28#ifdef __ARM_ARCH
     29        // function prototypes are only really used by these macros on ARM
     30        void disable_global_interrupts();
     31        void enable_global_interrupts();
     32
     33        #define TL_GET( member ) ( { __typeof__( kernelTLS.member ) target; \
     34                disable_global_interrupts(); \
     35                target = kernelTLS.member; \
     36                enable_global_interrupts(); \
     37                target; } )
     38        #define TL_SET( member, value ) disable_global_interrupts(); \
     39                kernelTLS.member = value; \
     40                enable_global_interrupts();
     41#else
     42        #define TL_GET( member ) kernelTLS.member
     43        #define TL_SET( member, value ) kernelTLS.member = value;
     44#endif
    3045
    3146        #ifdef __cforall
  • src/libcfa/concurrency/kernel

    r0182bfa r28f3a19  
    2323extern "C" {
    2424#include <pthread.h>
     25#include <semaphore.h>
    2526}
    2627
     
    4344extern struct cluster * mainCluster;
    4445
    45 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule };
     46enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule, Callback };
     47
     48typedef void (*__finish_callback_fptr_t)(void);
    4649
    4750//TODO use union, many of these fields are mutually exclusive (i.e. MULTI vs NOMULTI)
    4851struct FinishAction {
    4952        FinishOpCode action_code;
     53        /*
     54        // Union of possible actions
     55        union {
     56                // Option 1 : locks and threads
     57                struct {
     58                        // 1 thread or N thread
     59                        union {
     60                                thread_desc * thrd;
     61                                struct {
     62                                        thread_desc ** thrds;
     63                                        unsigned short thrd_count;
     64                                };
     65                        };
     66                        // 1 lock or N lock
     67                        union {
     68                                __spinlock_t * lock;
     69                                struct {
     70                                        __spinlock_t ** locks;
     71                                        unsigned short lock_count;
     72                                };
     73                        };
     74                };
     75                // Option 2 : action pointer
     76                __finish_callback_fptr_t callback;
     77        };
     78        /*/
    5079        thread_desc * thrd;
     80        thread_desc ** thrds;
     81        unsigned short thrd_count;
    5182        __spinlock_t * lock;
    5283        __spinlock_t ** locks;
    5384        unsigned short lock_count;
    54         thread_desc ** thrds;
    55         unsigned short thrd_count;
     85        __finish_callback_fptr_t callback;
     86        //*/
    5687};
    5788static inline void ?{}(FinishAction & this) {
     
    82113        pthread_t kernel_thread;
    83114
     115        // RunThread data
     116        // Action to do after a thread is ran
     117        struct FinishAction finish;
     118
     119        // Preemption data
     120        // Node which is added in the discrete event simulaiton
     121        struct alarm_node_t * preemption_alarm;
     122
     123        // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
     124        bool pending_preemption;
     125
     126        // Idle lock
     127        __bin_sem_t idleLock;
     128
    84129        // Termination
    85130        // Set to true to notify the processor should terminate
     
    89134        semaphore terminated;
    90135
    91         // RunThread data
    92         // Action to do after a thread is ran
    93         struct FinishAction finish;
    94 
    95         // Preemption data
    96         // Node which is added in the discrete event simulaiton
    97         struct alarm_node_t * preemption_alarm;
    98 
    99         // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible
    100         bool pending_preemption;
    101 
    102         // Idle lock
    103 
    104136        // Link lists fields
    105         struct {
     137        struct __dbg_node_proc {
    106138                struct processor * next;
    107139                struct processor * prev;
     
    150182
    151183        // Link lists fields
    152         struct {
     184        struct __dbg_node_cltr {
    153185                cluster * next;
    154186                cluster * prev;
  • src/libcfa/concurrency/kernel.c

    r0182bfa r28f3a19  
    1616//C Includes
    1717#include <stddef.h>
     18#include <errno.h>
     19#include <string.h>
    1820extern "C" {
    1921#include <stdio.h>
     
    4951thread_desc * mainThread;
    5052
    51 struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
     53extern "C" {
     54struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters;
     55}
    5256
    5357//-----------------------------------------------------------------------------
     
    143147        runner.proc = &this;
    144148
     149        idleLock{};
     150
    145151        start( &this );
    146152}
    147153
    148154void ^?{}(processor & this) with( this ){
    149         if( ! do_terminate ) {
     155        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
    150156                __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this);
    151                 terminate(&this);
    152                 verify(this.do_terminate);
    153                 verify( kernelTLS.this_processor != &this);
     157
     158                __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED);
     159                wake( &this );
     160
    154161                P( terminated );
    155162                verify( kernelTLS.this_processor != &this);
    156                 pthread_join( kernel_thread, NULL );
    157         }
     163        }
     164
     165        pthread_join( kernel_thread, NULL );
    158166}
    159167
     
    194202
    195203                thread_desc * readyThread = NULL;
    196                 for( unsigned int spin_count = 0; ! this->do_terminate; spin_count++ )
     204                for( unsigned int spin_count = 0; ! __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST); spin_count++ )
    197205                {
    198206                        readyThread = nextThread( this->cltr );
     
    213221                        else
    214222                        {
    215                                 spin(this, &spin_count);
     223                                // spin(this, &spin_count);
     224                                halt(this);
    216225                        }
    217226                }
     
    257266// its final actions must be executed from the kernel
    258267void finishRunning(processor * this) with( this->finish ) {
    259         if( action_code == Release ) {
    260                 verify( ! kernelTLS.preemption_state.enabled );
     268        verify( ! kernelTLS.preemption_state.enabled );
     269        choose( action_code ) {
     270        case No_Action:
     271                break;
     272        case Release:
    261273                unlock( *lock );
    262         }
    263         else if( action_code == Schedule ) {
     274        case Schedule:
    264275                ScheduleThread( thrd );
    265         }
    266         else if( action_code == Release_Schedule ) {
    267                 verify( ! kernelTLS.preemption_state.enabled );
     276        case Release_Schedule:
    268277                unlock( *lock );
    269278                ScheduleThread( thrd );
    270         }
    271         else if( action_code == Release_Multi ) {
    272                 verify( ! kernelTLS.preemption_state.enabled );
     279        case Release_Multi:
    273280                for(int i = 0; i < lock_count; i++) {
    274281                        unlock( *locks[i] );
    275282                }
    276         }
    277         else if( action_code == Release_Multi_Schedule ) {
     283        case Release_Multi_Schedule:
    278284                for(int i = 0; i < lock_count; i++) {
    279285                        unlock( *locks[i] );
     
    282288                        ScheduleThread( thrds[i] );
    283289                }
    284         }
    285         else {
    286                 assert(action_code == No_Action);
    287         }
    288 }
    289 
    290 // Handles spinning logic
    291 // TODO : find some strategy to put cores to sleep after some time
    292 void spin(processor * this, unsigned int * spin_count) {
    293         (*spin_count)++;
     290        case Callback:
     291                callback();
     292        default:
     293                abort("KERNEL ERROR: Unexpected action to run after thread");
     294        }
    294295}
    295296
     
    396397        with( *thrd->curr_cluster ) {
    397398                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
     399                bool was_empty = !(ready_queue != 0);
    398400                append( ready_queue, thrd );
    399401                unlock( ready_queue_lock );
     402
     403                if(was_empty) {
     404                        lock      (proc_list_lock __cfaabi_dbg_ctx2);
     405                        if(idles) {
     406                                wake_fast(idles.head);
     407                        }
     408                        unlock    (proc_list_lock);
     409                }
     410                else if( struct processor * idle = idles.head ) {
     411                        wake_fast(idle);
     412                }
     413
    400414        }
    401415
     
    497511}
    498512
     513void BlockInternal(__finish_callback_fptr_t callback) {
     514        disable_interrupts();
     515        with( *kernelTLS.this_processor ) {
     516                finish.action_code = Callback;
     517                finish.callback    = callback;
     518        }
     519
     520        verify( ! kernelTLS.preemption_state.enabled );
     521        returnToKernel();
     522        verify( ! kernelTLS.preemption_state.enabled );
     523
     524        enable_interrupts( __cfaabi_dbg_ctx );
     525}
     526
    499527// KERNEL ONLY
    500528void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
     
    518546        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    519547
    520         global_clusters.list{ __get };
    521         global_clusters.lock{};
     548        __cfa_dbg_global_clusters.list{ __get };
     549        __cfa_dbg_global_clusters.lock{};
    522550
    523551        // Initialize the main cluster
     
    600628        // When its coroutine terminates, it return control to the mainThread
    601629        // which is currently here
    602         mainProcessor->do_terminate = true;
     630        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    603631        returnToKernel();
     632        mainThread->self_cor.state = Halted;
    604633
    605634        // THE SYSTEM IS NOW COMPLETELY STOPPED
     
    617646        ^(mainThread){};
    618647
    619         ^(global_clusters.list){};
    620         ^(global_clusters.lock){};
     648        ^(__cfa_dbg_global_clusters.list){};
     649        ^(__cfa_dbg_global_clusters.lock){};
    621650
    622651        __cfaabi_dbg_print_safe("Kernel : Shutdown complete\n");
     
    627656//=============================================================================================
    628657
    629 // void halt(processor * this) with( this ) {
    630 //      pthread_mutex_lock( &idle.lock );
    631 
    632 
    633 
    634 //      // SKULLDUGGERY: Even if spurious wake-up is a thing
    635 //      // spuriously waking up a kernel thread is not a big deal
    636 //      // if it is very rare.
    637 //      pthread_cond_wait( &idle.cond, &idle.lock);
    638 //      pthread_mutex_unlock( &idle.lock );
    639 // }
    640 
    641 // void wake(processor * this) with( this ) {
    642 //      pthread_mutex_lock  (&idle.lock);
    643 //      pthread_cond_signal (&idle.cond);
    644 //      pthread_mutex_unlock(&idle.lock);
    645 // }
     658void halt(processor * this) with( *this ) {
     659        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
     660
     661        with( *cltr ) {
     662                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     663                remove    (procs, *this);
     664                push_front(idles, *this);
     665                unlock    (proc_list_lock);
     666        }
     667
     668        __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
     669
     670        wait( idleLock );
     671
     672        __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     673
     674        with( *cltr ) {
     675                lock      (proc_list_lock __cfaabi_dbg_ctx2);
     676                remove    (idles, *this);
     677                push_front(procs, *this);
     678                unlock    (proc_list_lock);
     679        }
     680}
    646681
    647682//=============================================================================================
     
    758793// Global Queues
    759794void doregister( cluster     & cltr ) {
    760         lock      ( global_clusters.lock __cfaabi_dbg_ctx2);
    761         push_front( global_clusters.list, cltr );
    762         unlock    ( global_clusters.lock );
     795        lock      ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2);
     796        push_front( __cfa_dbg_global_clusters.list, cltr );
     797        unlock    ( __cfa_dbg_global_clusters.lock );
    763798}
    764799
    765800void unregister( cluster     & cltr ) {
    766         lock  ( global_clusters.lock __cfaabi_dbg_ctx2);
    767         remove( global_clusters.list, cltr );
    768         unlock( global_clusters.lock );
     801        lock  ( __cfa_dbg_global_clusters.lock __cfaabi_dbg_ctx2);
     802        remove( __cfa_dbg_global_clusters.list, cltr );
     803        unlock( __cfa_dbg_global_clusters.lock );
    769804}
    770805
  • src/libcfa/concurrency/kernel_private.h

    r0182bfa r28f3a19  
    4848void BlockInternal(__spinlock_t * locks [], unsigned short count);
    4949void BlockInternal(__spinlock_t * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count);
     50void BlockInternal(__finish_callback_fptr_t callback);
    5051void LeaveThread(__spinlock_t * lock, thread_desc * thrd);
    5152
     
    5657void runThread(processor * this, thread_desc * dst);
    5758void finishRunning(processor * this);
    58 void terminate(processor * this);
    59 void spin(processor * this, unsigned int * spin_count);
     59void halt(processor * this);
     60
     61static inline void wake_fast(processor * this) {
     62        __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);
     63        post( this->idleLock );
     64}
     65
     66static inline void wake(processor * this) {
     67        disable_interrupts();
     68        wake_fast(this);
     69        enable_interrupts( __cfaabi_dbg_ctx );
     70}
    6071
    6172struct event_kernel_t {
     
    6576
    6677extern event_kernel_t * event_kernel;
    67 
    68 //extern thread_local coroutine_desc * volatile this_coroutine;
    69 //extern thread_local thread_desc *    volatile this_thread;
    70 //extern thread_local processor *      volatile this_processor;
    71 
    72 // extern volatile thread_local bool preemption_in_progress;
    73 // extern volatile thread_local bool preemption_enabled;
    74 // extern volatile thread_local unsigned short disable_preempt_count;
    7578
    7679struct __cfa_kernel_preemption_state_t {
  • src/libcfa/concurrency/monitor.c

    r0182bfa r28f3a19  
    297297        this.count = count;
    298298
    299         // Sort monitors based on address -> TODO use a sort specialized for small numbers
     299        // Sort monitors based on address
    300300        __libcfa_small_sort(this.m, count);
    301301
  • src/libcfa/concurrency/preemption.c

    r0182bfa r28f3a19  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 13:52:39 2018
    13 // Update Count     : 36
     12// Last Modified On : Tue Jun  5 17:35:49 2018
     13// Update Count     : 37
    1414//
    1515
     
    116116        // If there are still alarms pending, reset the timer
    117117        if( alarms->head ) {
    118                 __cfaabi_dbg_print_buffer_decl( " KERNEL: @%lu(%lu) resetting alarm to %lu.\n", currtime.tv, __kernel_get_time().tv, (alarms->head->alarm - currtime).tv);
     118                __cfaabi_dbg_print_buffer_decl( " KERNEL: @%ju(%ju) resetting alarm to %ju.\n", currtime.tv, __kernel_get_time().tv, (alarms->head->alarm - currtime).tv);
    119119                Duration delta = alarms->head->alarm - currtime;
    120120                Duration caped = max(delta, 50`us);
     
    161161        void disable_interrupts() {
    162162                with( kernelTLS.preemption_state ) {
     163                        #if GCC_VERSION > 50000
    163164                        static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
     165                        #endif
    164166
    165167                        // Set enabled flag to false
     
    190192                        // Check if we need to prempt the thread because an interrupt was missed
    191193                        if( prev == 1 ) {
     194                                #if GCC_VERSION > 50000
    192195                                static_assert(__atomic_always_lock_free(sizeof(enabled), &enabled), "Must be lock-free");
     196                                #endif
    193197
    194198                                // Set enabled flag to true
     
    217221                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    218222                if( prev == 1 ) {
     223                        #if GCC_VERSION > 50000
    219224                        static_assert(__atomic_always_lock_free(sizeof(kernelTLS.preemption_state.enabled), &kernelTLS.preemption_state.enabled), "Must be lock-free");
     225                        #endif
    220226                        // Set enabled flag to true
    221227                        // should be atomic to avoid preemption in the middle of the operation.
     
    254260static void preempt( processor * this ) {
    255261        sigval_t value = { PREEMPT_NORMAL };
    256         pthread_sigqueue( this->kernel_thread, SIGUSR1, value );
    257 }
    258 
    259 // kill wrapper : signal a processor
    260 void terminate(processor * this) {
    261         this->do_terminate = true;
    262         sigval_t value = { PREEMPT_TERMINATE };
    263262        pthread_sigqueue( this->kernel_thread, SIGUSR1, value );
    264263}
     
    362361        choose(sfp->si_value.sival_int) {
    363362                case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    364                 case PREEMPT_TERMINATE: verify( kernelTLS.this_processor->do_terminate);
     363                case PREEMPT_TERMINATE: verify( __atomic_load_n( &kernelTLS.this_processor->do_terminate, __ATOMIC_SEQ_CST ) );
    365364                default:
    366365                        abort( "internal error, signal value is %d", sfp->si_value.sival_int );
     
    376375
    377376        // Clear sighandler mask before context switching.
     377        #if GCC_VERSION > 50000
    378378        static_assert( sizeof( sigset_t ) == sizeof( cxt->uc_sigmask ), "Expected cxt->uc_sigmask to be of sigset_t" );
     379        #endif
    379380        if ( pthread_sigmask( SIG_SETMASK, (sigset_t *)&(cxt->uc_sigmask), NULL ) == -1 ) {
    380381                abort( "internal error, sigprocmask" );
     
    479480}
    480481
     482#ifdef __CFA_WITH_VERIFY__
     483bool __cfaabi_dbg_in_kernel() {
     484        return !kernelTLS.preemption_state.enabled;
     485}
     486#endif
     487
    481488// Local Variables: //
    482489// mode: c //
  • src/libcfa/fstream

    r0182bfa r28f3a19  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec  7 15:17:26 2017
    13 // Update Count     : 130
     12// Last Modified On : Tue Jun  5 10:20:25 2018
     13// Update Count     : 131
    1414//
    1515
     
    5454void open( ofstream &, const char * name );
    5555void close( ofstream & );
    56 ofstream & write( ofstream &, const char * data, unsigned long int size );
     56ofstream & write( ofstream &, const char * data, size_t size );
    5757int fmt( ofstream &, const char fmt[], ... );
    5858
     
    7474void open( ifstream & is, const char * name );
    7575void close( ifstream & is );
    76 ifstream & read( ifstream & is, char * data, unsigned long int size );
     76ifstream & read( ifstream & is, char * data, size_t size );
    7777ifstream & ungetc( ifstream & is, char c );
    7878int fmt( ifstream &, const char fmt[], ... );
  • src/libcfa/fstream.c

    r0182bfa r28f3a19  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Dec  9 09:31:23 2017
    13 // Update Count     : 275
     12// Last Modified On : Tue Jun  5 17:02:56 2018
     13// Update Count     : 281
    1414//
    1515
     
    116116} // close
    117117
    118 ofstream & write( ofstream & os, const char * data, unsigned long int size ) {
     118ofstream & write( ofstream & os, const char * data, size_t size ) {
    119119        if ( fail( os ) ) {
    120120                fprintf( stderr, "attempt write I/O on failed stream\n" );
     
    198198} // close
    199199
    200 ifstream & read( ifstream & is, char * data, unsigned long int size ) {
     200ifstream & read( ifstream & is, char * data, size_t size ) {
    201201        if ( fail( is ) ) {
    202202                fprintf( stderr, "attempt read I/O on failed stream\n" );
  • src/libcfa/iostream

    r0182bfa r28f3a19  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 28 13:08:24 2018
    13 // Update Count     : 152
     12// Last Modified On : Sat Jun  2 08:07:55 2018
     13// Update Count     : 153
    1414//
    1515
     
    5656// implement writable for intrinsic types
    5757
    58 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, _Bool );
     58forall( dtype ostype | ostream( ostype ) ) {
     59        ostype & ?|?( ostype &, _Bool );
    5960
    60 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, char );
    61 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, signed char );
    62 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, unsigned char );
     61        ostype & ?|?( ostype &, char );
     62        ostype & ?|?( ostype &, signed char );
     63        ostype & ?|?( ostype &, unsigned char );
    6364
    64 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, short int );
    65 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, unsigned short int );
    66 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, int );
    67 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, unsigned int );
    68 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, long int );
    69 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, long long int );
    70 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, unsigned long int );
    71 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, unsigned long long int );
     65        ostype & ?|?( ostype &, short int );
     66        ostype & ?|?( ostype &, unsigned short int );
     67        ostype & ?|?( ostype &, int );
     68        ostype & ?|?( ostype &, unsigned int );
     69        ostype & ?|?( ostype &, long int );
     70        ostype & ?|?( ostype &, long long int );
     71        ostype & ?|?( ostype &, unsigned long int );
     72        ostype & ?|?( ostype &, unsigned long long int );
    7273
    73 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, float ); // FIX ME: should not be required
    74 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, double );
    75 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, long double );
     74        ostype & ?|?( ostype &, float ); // FIX ME: should not be required
     75        ostype & ?|?( ostype &, double );
     76        ostype & ?|?( ostype &, long double );
    7677
    77 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, float _Complex );
    78 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, double _Complex );
    79 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, long double _Complex );
     78        ostype & ?|?( ostype &, float _Complex );
     79        ostype & ?|?( ostype &, double _Complex );
     80        ostype & ?|?( ostype &, long double _Complex );
    8081
    81 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, const char * );
    82 //forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, const char16_t * );
     82        ostype & ?|?( ostype &, const char * );
     83        // ostype & ?|?( ostype &, const char16_t * );
    8384#if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    84 //forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, const char32_t * );
     85        // ostype & ?|?( ostype &, const char32_t * );
    8586#endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    86 //forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, const wchar_t * );
    87 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, const void * );
     87        // ostype & ?|?( ostype &, const wchar_t * );
     88        ostype & ?|?( ostype &, const void * );
     89
     90        // manipulators
     91        ostype & ?|?( ostype &, ostype & (*)( ostype & ) );
     92        ostype & endl( ostype & );
     93        ostype & sep( ostype & );
     94        ostype & sepTuple( ostype & );
     95        ostype & sepOn( ostype & );
     96        ostype & sepOff( ostype & );
     97        ostype & sepDisable( ostype & );
     98        ostype & sepEnable( ostype & );
     99} // distribution
    88100
    89101// tuples
    90102forall( dtype ostype, otype T, ttype Params | writeable( T, ostype ) | { ostype & ?|?( ostype &, Params ); } )
    91103ostype & ?|?( ostype & os, T arg, Params rest );
    92 
    93 // manipulators
    94 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype &, ostype & (*)( ostype & ) );
    95 forall( dtype ostype | ostream( ostype ) ) ostype & endl( ostype & );
    96 forall( dtype ostype | ostream( ostype ) ) ostype & sep( ostype & );
    97 forall( dtype ostype | ostream( ostype ) ) ostype & sepTuple( ostype & );
    98 forall( dtype ostype | ostream( ostype ) ) ostype & sepOn( ostype & );
    99 forall( dtype ostype | ostream( ostype ) ) ostype & sepOff( ostype & );
    100 forall( dtype ostype | ostream( ostype ) ) ostype & sepDisable( ostype & );
    101 forall( dtype ostype | ostream( ostype ) ) ostype & sepEnable( ostype & );
    102104
    103105// writes the range [begin, end) to the given stream
     
    124126}; // readable
    125127
    126 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Bool & );
     128forall( dtype istype | istream( istype ) ) {
     129        istype & ?|?( istype &, _Bool & );
    127130
    128 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, char & );
    129 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, signed char & );
    130 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, unsigned char & );
     131        istype & ?|?( istype &, char & );
     132        istype & ?|?( istype &, signed char & );
     133        istype & ?|?( istype &, unsigned char & );
    131134
    132 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, short int & );
    133 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, unsigned short int & );
    134 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, int & );
    135 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, unsigned int & );
    136 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, long int & );
    137 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, long long int & );
    138 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, unsigned long int & );
    139 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, unsigned long long int & );
     135        istype & ?|?( istype &, short int & );
     136        istype & ?|?( istype &, unsigned short int & );
     137        istype & ?|?( istype &, int & );
     138        istype & ?|?( istype &, unsigned int & );
     139        istype & ?|?( istype &, long int & );
     140        istype & ?|?( istype &, long long int & );
     141        istype & ?|?( istype &, unsigned long int & );
     142        istype & ?|?( istype &, unsigned long long int & );
    140143
    141 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, float & );
    142 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, double & );
    143 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, long double & );
     144        istype & ?|?( istype &, float & );
     145        istype & ?|?( istype &, double & );
     146        istype & ?|?( istype &, long double & );
    144147
    145 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, float _Complex & );
    146 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, double _Complex & );
    147 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, long double _Complex & );
     148        istype & ?|?( istype &, float _Complex & );
     149        istype & ?|?( istype &, double _Complex & );
     150        istype & ?|?( istype &, long double _Complex & );
    148151
    149 // manipulators
    150 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, istype & (*)( istype & ) );
    151 forall( dtype istype | istream( istype ) ) istype & endl( istype & is );
     152        // manipulators
     153        istype & ?|?( istype &, istype & (*)( istype & ) );
     154        istype & endl( istype & is );
     155} // distribution
    152156
    153157struct _Istream_cstrUC { char * s; };
  • src/libcfa/iostream.c

    r0182bfa r28f3a19  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 28 13:08:25 2018
    13 // Update Count     : 469
     12// Last Modified On : Sat Jun  2 08:24:56 2018
     13// Update Count     : 471
    1414//
    1515
     
    2626}
    2727
    28 forall( dtype ostype | ostream( ostype ) )
    29 ostype & ?|?( ostype & os, _Bool b ) {
    30         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    31         fmt( os, "%s", b ? "true" : "false" );
    32         return os;
    33 } // ?|?
    34 
    35 forall( dtype ostype | ostream( ostype ) )
    36 ostype & ?|?( ostype & os, char ch ) {
    37         fmt( os, "%c", ch );
    38         if ( ch == '\n' ) setNL( os, true );
    39         sepOff( os );
    40         return os;
    41 } // ?|?
    42 
    43 forall( dtype ostype | ostream( ostype ) )
    44 ostype & ?|?( ostype & os, signed char c ) {
    45         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    46         fmt( os, "%hhd", c );
    47         return os;
    48 } // ?|?
    49 
    50 forall( dtype ostype | ostream( ostype ) )
    51 ostype & ?|?( ostype & os, unsigned char c ) {
    52         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    53         fmt( os, "%hhu", c );
    54         return os;
    55 } // ?|?
    56 
    57 forall( dtype ostype | ostream( ostype ) )
    58 ostype & ?|?( ostype & os, short int si ) {
    59         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    60         fmt( os, "%hd", si );
    61         return os;
    62 } // ?|?
    63 
    64 forall( dtype ostype | ostream( ostype ) )
    65 ostype & ?|?( ostype & os, unsigned short int usi ) {
    66         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    67         fmt( os, "%hu", usi );
    68         return os;
    69 } // ?|?
    70 
    71 forall( dtype ostype | ostream( ostype ) )
    72 ostype & ?|?( ostype & os, int i ) {
    73         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    74         fmt( os, "%d", i );
    75         return os;
    76 } // ?|?
    77 
    78 forall( dtype ostype | ostream( ostype ) )
    79 ostype & ?|?( ostype & os, unsigned int ui ) {
    80         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    81         fmt( os, "%u", ui );
    82         return os;
    83 } // ?|?
    84 
    85 forall( dtype ostype | ostream( ostype ) )
    86 ostype & ?|?( ostype & os, long int li ) {
    87         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    88         fmt( os, "%ld", li );
    89         return os;
    90 } // ?|?
    91 
    92 forall( dtype ostype | ostream( ostype ) )
    93 ostype & ?|?( ostype & os, unsigned long int uli ) {
    94         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    95         fmt( os, "%lu", uli );
    96         return os;
    97 } // ?|?
    98 
    99 forall( dtype ostype | ostream( ostype ) )
    100 ostype & ?|?( ostype & os, long long int lli ) {
    101         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    102         fmt( os, "%lld", lli );
    103         return os;
    104 } // ?|?
    105 
    106 forall( dtype ostype | ostream( ostype ) )
    107 ostype & ?|?( ostype & os, unsigned long long int ulli ) {
    108         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    109         fmt( os, "%llu", ulli );
    110         return os;
    111 } // ?|?
    112 
    113 forall( dtype ostype | ostream( ostype ) )
    114 ostype & ?|?( ostype & os, float f ) {
    115         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    116         fmt( os, "%g", f );
    117         return os;
    118 } // ?|?
    119 
    120 forall( dtype ostype | ostream( ostype ) )
    121 ostype & ?|?( ostype & os, double d ) {
    122         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    123         fmt( os, "%.*lg", DBL_DIG, d );
    124         return os;
    125 } // ?|?
    126 
    127 forall( dtype ostype | ostream( ostype ) )
    128 ostype & ?|?( ostype & os, long double ld ) {
    129         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    130         fmt( os, "%.*Lg", LDBL_DIG, ld );
    131         return os;
    132 } // ?|?
    133 
    134 forall( dtype ostype | ostream( ostype ) )
    135 ostype & ?|?( ostype & os, float _Complex fc ) {
    136         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    137         fmt( os, "%g%+gi", crealf( fc ), cimagf( fc ) );
    138         return os;
    139 } // ?|?
    140 
    141 forall( dtype ostype | ostream( ostype ) )
    142 ostype & ?|?( ostype & os, double _Complex dc ) {
    143         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    144         fmt( os, "%.*lg%+.*lgi", DBL_DIG, creal( dc ), DBL_DIG, cimag( dc ) );
    145         return os;
    146 } // ?|?
    147 
    148 forall( dtype ostype | ostream( ostype ) )
    149 ostype & ?|?( ostype & os, long double _Complex ldc ) {
    150         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    151         fmt( os, "%.*Lg%+.*Lgi", LDBL_DIG, creall( ldc ), LDBL_DIG, cimagl( ldc ) );
    152         return os;
    153 } // ?|?
    154 
    155 forall( dtype ostype | ostream( ostype ) )
    156 ostype & ?|?( ostype & os, const char * str ) {
    157         enum { Open = 1, Close, OpenClose };
    158         static const unsigned char mask[256] @= {
    159                 // opening delimiters, no space after
    160                 ['('] : Open, ['['] : Open, ['{'] : Open,
    161                 ['='] : Open, ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open,
    162                 [(unsigned char)'¡'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
    163                 // closing delimiters, no space before
    164                 [','] : Close, ['.'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
    165                 ['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
    166                 [')'] : Close, [']'] : Close, ['}'] : Close,
    167                 // opening-closing delimiters, no space before or after
    168                 ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, [':'] : OpenClose,
    169                 [' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
    170         }; // mask
    171 
    172   if ( str[0] == '\0' ) { sepOff( os ); return os; }            // null string => no separator
    173 
    174         // first character IS NOT spacing or closing punctuation => add left separator
    175         unsigned char ch = str[0];                                                      // must make unsigned
    176         if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    177                 fmt( os, "%s", sepGetCur( os ) );
    178         } // if
    179 
    180         // if string starts line, must reset to determine open state because separator is off
    181         sepReset( os );                                                                         // reset separator
    182 
    183         // last character IS spacing or opening punctuation => turn off separator for next item
    184         size_t len = strlen( str );
    185         ch = str[len - 1];                                                                      // must make unsigned
    186         if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     28forall( dtype ostype | ostream( ostype ) ) {
     29        ostype & ?|?( ostype & os, _Bool b ) {
     30                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     31                fmt( os, "%s", b ? "true" : "false" );
     32                return os;
     33        } // ?|?
     34
     35        ostype & ?|?( ostype & os, char ch ) {
     36                fmt( os, "%c", ch );
     37                if ( ch == '\n' ) setNL( os, true );
     38                sepOff( os );
     39                return os;
     40        } // ?|?
     41
     42        ostype & ?|?( ostype & os, signed char c ) {
     43                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     44                fmt( os, "%hhd", c );
     45                return os;
     46        } // ?|?
     47
     48        ostype & ?|?( ostype & os, unsigned char c ) {
     49                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     50                fmt( os, "%hhu", c );
     51                return os;
     52        } // ?|?
     53
     54        ostype & ?|?( ostype & os, short int si ) {
     55                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     56                fmt( os, "%hd", si );
     57                return os;
     58        } // ?|?
     59
     60        ostype & ?|?( ostype & os, unsigned short int usi ) {
     61                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     62                fmt( os, "%hu", usi );
     63                return os;
     64        } // ?|?
     65
     66        ostype & ?|?( ostype & os, int i ) {
     67                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     68                fmt( os, "%d", i );
     69                return os;
     70        } // ?|?
     71
     72        ostype & ?|?( ostype & os, unsigned int ui ) {
     73                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     74                fmt( os, "%u", ui );
     75                return os;
     76        } // ?|?
     77
     78        ostype & ?|?( ostype & os, long int li ) {
     79                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     80                fmt( os, "%ld", li );
     81                return os;
     82        } // ?|?
     83
     84        ostype & ?|?( ostype & os, unsigned long int uli ) {
     85                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     86                fmt( os, "%lu", uli );
     87                return os;
     88        } // ?|?
     89
     90        ostype & ?|?( ostype & os, long long int lli ) {
     91                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     92                fmt( os, "%lld", lli );
     93                return os;
     94        } // ?|?
     95
     96        ostype & ?|?( ostype & os, unsigned long long int ulli ) {
     97                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     98                fmt( os, "%llu", ulli );
     99                return os;
     100        } // ?|?
     101
     102        ostype & ?|?( ostype & os, float f ) {
     103                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     104                fmt( os, "%g", f );
     105                return os;
     106        } // ?|?
     107
     108        ostype & ?|?( ostype & os, double d ) {
     109                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     110                fmt( os, "%.*lg", DBL_DIG, d );
     111                return os;
     112        } // ?|?
     113
     114        ostype & ?|?( ostype & os, long double ld ) {
     115                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     116                fmt( os, "%.*Lg", LDBL_DIG, ld );
     117                return os;
     118        } // ?|?
     119
     120        ostype & ?|?( ostype & os, float _Complex fc ) {
     121                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     122                fmt( os, "%g%+gi", crealf( fc ), cimagf( fc ) );
     123                return os;
     124        } // ?|?
     125
     126        ostype & ?|?( ostype & os, double _Complex dc ) {
     127                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     128                fmt( os, "%.*lg%+.*lgi", DBL_DIG, creal( dc ), DBL_DIG, cimag( dc ) );
     129                return os;
     130        } // ?|?
     131
     132        ostype & ?|?( ostype & os, long double _Complex ldc ) {
     133                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     134                fmt( os, "%.*Lg%+.*Lgi", LDBL_DIG, creall( ldc ), LDBL_DIG, cimagl( ldc ) );
     135                return os;
     136        } // ?|?
     137
     138        ostype & ?|?( ostype & os, const char * str ) {
     139                enum { Open = 1, Close, OpenClose };
     140                static const unsigned char mask[256] @= {
     141                        // opening delimiters, no space after
     142                        ['('] : Open, ['['] : Open, ['{'] : Open,
     143                        ['='] : Open, ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open,
     144                        [(unsigned char)'¡'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
     145                        // closing delimiters, no space before
     146                        [','] : Close, ['.'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
     147                        ['%'] : Close, [(unsigned char)'¢'] : Close, [(unsigned char)'»'] : Close,
     148                        [')'] : Close, [']'] : Close, ['}'] : Close,
     149                        // opening-closing delimiters, no space before or after
     150                        ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, [':'] : OpenClose,
     151                        [' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
     152                }; // mask
     153
     154          if ( str[0] == '\0' ) { sepOff( os ); return os; } // null string => no separator
     155
     156                // first character IS NOT spacing or closing punctuation => add left separator
     157                unsigned char ch = str[0];                                              // must make unsigned
     158                if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     159                        fmt( os, "%s", sepGetCur( os ) );
     160                } // if
     161
     162                // if string starts line, must reset to determine open state because separator is off
     163                sepReset( os );                                                                 // reset separator
     164
     165                // last character IS spacing or opening punctuation => turn off separator for next item
     166                size_t len = strlen( str );
     167                ch = str[len - 1];                                                              // must make unsigned
     168                if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     169                        sepOn( os );
     170                } else {
     171                        sepOff( os );
     172                } // if
     173                if ( ch == '\n' ) setNL( os, true );                    // check *AFTER* sepPrt call above as it resets NL flag
     174                return write( os, str, len );
     175        } // ?|?
     176
     177//      ostype & ?|?( ostype & os, const char16_t * str ) {
     178//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     179//              fmt( os, "%ls", str );
     180//              return os;
     181//      } // ?|?
     182
     183// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
     184//      ostype & ?|?( ostype & os, const char32_t * str ) {
     185//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     186//              fmt( os, "%ls", str );
     187//              return os;
     188//      } // ?|?
     189// #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
     190
     191//      ostype & ?|?( ostype & os, const wchar_t * str ) {
     192//              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     193//              fmt( os, "%ls", str );
     194//              return os;
     195//      } // ?|?
     196
     197        ostype & ?|?( ostype & os, const void * p ) {
     198                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     199                fmt( os, "%p", p );
     200                return os;
     201        } // ?|?
     202
     203
     204        // manipulators
     205        ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
     206                return manip( os );
     207        } // ?|?
     208
     209        ostype & sep( ostype & os ) {
     210                os | sepGet( os );
     211                return os;
     212        } // sep
     213
     214        ostype & sepTuple( ostype & os ) {
     215                os | sepGetTuple( os );
     216                return os;
     217        } // sepTuple
     218
     219        ostype & endl( ostype & os ) {
     220                os | '\n';
     221                setNL( os, true );
     222                flush( os );
     223                sepOff( os );                                                                   // prepare for next line
     224                return os;
     225        } // endl
     226
     227        ostype & sepOn( ostype & os ) {
    187228                sepOn( os );
    188         } else {
     229                return os;
     230        } // sepOn
     231
     232        ostype & sepOff( ostype & os ) {
    189233                sepOff( os );
    190         } // if
    191         if ( ch == '\n' ) setNL( os, true );                            // check *AFTER* sepPrt call above as it resets NL flag
    192         return write( os, str, len );
    193 } // ?|?
    194 
    195 // forall( dtype ostype | ostream( ostype ) )
    196 // ostype & ?|?( ostype & os, const char16_t * str ) {
    197 //      if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    198 //      fmt( os, "%ls", str );
    199 //      return os;
    200 // } // ?|?
    201 
    202 // #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    203 // forall( dtype ostype | ostream( ostype ) )
    204 // ostype & ?|?( ostype & os, const char32_t * str ) {
    205 //      if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    206 //      fmt( os, "%ls", str );
    207 //      return os;
    208 // } // ?|?
    209 // #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    210 
    211 // forall( dtype ostype | ostream( ostype ) )
    212 // ostype & ?|?( ostype & os, const wchar_t * str ) {
    213 //      if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    214 //      fmt( os, "%ls", str );
    215 //      return os;
    216 // } // ?|?
    217 
    218 forall( dtype ostype | ostream( ostype ) )
    219 ostype & ?|?( ostype & os, const void * p ) {
    220         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    221         fmt( os, "%p", p );
    222         return os;
    223 } // ?|?
     234                return os;
     235        } // sepOff
     236
     237        ostype & sepEnable( ostype & os ) {
     238                sepEnable( os );
     239                return os;
     240        } // sepEnable
     241
     242        ostype & sepDisable( ostype & os ) {
     243                sepDisable( os );
     244                return os;
     245        } // sepDisable
     246} // distribution
    224247
    225248
     
    234257} // ?|?
    235258
    236 
    237 // manipulators
    238 forall( dtype ostype | ostream( ostype ) )
    239 ostype & ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    240         return manip( os );
    241 } // ?|?
    242 
    243 forall( dtype ostype | ostream( ostype ) )
    244 ostype & sep( ostype & os ) {
    245         os | sepGet( os );
    246         return os;
    247 } // sep
    248 
    249 forall( dtype ostype | ostream( ostype ) )
    250 ostype & sepTuple( ostype & os ) {
    251         os | sepGetTuple( os );
    252         return os;
    253 } // sepTuple
    254 
    255 forall( dtype ostype | ostream( ostype ) )
    256 ostype & endl( ostype & os ) {
    257         os | '\n';
    258         setNL( os, true );
    259         flush( os );
    260         sepOff( os );                                                                           // prepare for next line
    261         return os;
    262 } // endl
    263 
    264 forall( dtype ostype | ostream( ostype ) )
    265 ostype & sepOn( ostype & os ) {
    266         sepOn( os );
    267         return os;
    268 } // sepOn
    269 
    270 forall( dtype ostype | ostream( ostype ) )
    271 ostype & sepOff( ostype & os ) {
    272         sepOff( os );
    273         return os;
    274 } // sepOff
    275 
    276 forall( dtype ostype | ostream( ostype ) )
    277 ostype & sepEnable( ostype & os ) {
    278         sepEnable( os );
    279         return os;
    280 } // sepEnable
    281 
    282 forall( dtype ostype | ostream( ostype ) )
    283 ostype & sepDisable( ostype & os ) {
    284         sepDisable( os );
    285         return os;
    286 } // sepDisable
    287 
    288259//---------------------------------------
    289260
     261// writes the range [begin, end) to the given stream
    290262forall( dtype ostype, otype elt_type | writeable( elt_type, ostype ), otype iterator_type | iterator( iterator_type, elt_type ) )
    291263void write( iterator_type begin, iterator_type end, ostype & os ) {
     
    302274//---------------------------------------
    303275
    304 forall( dtype istype | istream( istype ) )
    305 istype & ?|?( istype & is, _Bool & b ) {
    306         char val[6];
    307         fmt( is, "%5s", val );
    308         if ( strcmp( val, "true" ) == 0 ) b = true;
    309         else if ( strcmp( val, "false" ) == 0 ) b = false;
    310         else {
    311                 fprintf( stderr, "invalid _Bool constant\n" );
    312                 abort();
    313         } // if
    314         return is;
    315 } // ?|?
    316 
    317 forall( dtype istype | istream( istype ) )
    318 istype & ?|?( istype & is, char & c ) {
    319         fmt( is, "%c", &c );                                                            // must pass pointer through varg to fmt
    320         return is;
    321 } // ?|?
    322 
    323 forall( dtype istype | istream( istype ) )
    324 istype & ?|?( istype & is, signed char & sc ) {
    325         fmt( is, "%hhd", &sc );
    326         return is;
    327 } // ?|?
    328 
    329 forall( dtype istype | istream( istype ) )
    330 istype & ?|?( istype & is, unsigned char & usc ) {
    331         fmt( is, "%hhu", &usc );
    332         return is;
    333 } // ?|?
    334 
    335 forall( dtype istype | istream( istype ) )
    336 istype & ?|?( istype & is, short int & si ) {
    337         fmt( is, "%hd", &si );
    338         return is;
    339 } // ?|?
    340 
    341 forall( dtype istype | istream( istype ) )
    342 istype & ?|?( istype & is, unsigned short int & usi ) {
    343         fmt( is, "%hu", &usi );
    344         return is;
    345 } // ?|?
    346 
    347 forall( dtype istype | istream( istype ) )
    348 istype & ?|?( istype & is, int & i ) {
    349         fmt( is, "%d", &i );
    350         return is;
    351 } // ?|?
    352 
    353 forall( dtype istype | istream( istype ) )
    354 istype & ?|?( istype & is, unsigned int & ui ) {
    355         fmt( is, "%u", &ui );
    356         return is;
    357 } // ?|?
    358 
    359 forall( dtype istype | istream( istype ) )
    360 istype & ?|?( istype & is, long int & li ) {
    361         fmt( is, "%ld", &li );
    362         return is;
    363 } // ?|?
    364 
    365 forall( dtype istype | istream( istype ) )
    366 istype & ?|?( istype & is, unsigned long int & ulli ) {
    367         fmt( is, "%lu", &ulli );
    368         return is;
    369 } // ?|?
    370 
    371 forall( dtype istype | istream( istype ) )
    372 istype & ?|?( istype & is, long long int & lli ) {
    373         fmt( is, "%lld", &lli );
    374         return is;
    375 } // ?|?
    376 
    377 forall( dtype istype | istream( istype ) )
    378 istype & ?|?( istype & is, unsigned long long int & ulli ) {
    379         fmt( is, "%llu", &ulli );
    380         return is;
    381 } // ?|?
    382 
    383 
    384 forall( dtype istype | istream( istype ) )
    385 istype & ?|?( istype & is, float & f ) {
    386         fmt( is, "%f", &f );
    387         return is;
    388 } // ?|?
    389 
    390 forall( dtype istype | istream( istype ) )
    391 istype & ?|?( istype & is, double & d ) {
    392         fmt( is, "%lf", &d );
    393         return is;
    394 } // ?|?
    395 
    396 forall( dtype istype | istream( istype ) )
    397 istype & ?|?( istype & is, long double & ld ) {
    398         fmt( is, "%Lf", &ld );
    399         return is;
    400 } // ?|?
    401 
    402 
    403 forall( dtype istype | istream( istype ) )
    404 istype & ?|?( istype & is, float _Complex & fc ) {
    405         float re, im;
    406         fmt( is, "%g%gi", &re, &im );
    407         fc = re + im * _Complex_I;
    408         return is;
    409 } // ?|?
    410 
    411 forall( dtype istype | istream( istype ) )
    412 istype & ?|?( istype & is, double _Complex & dc ) {
    413         double re, im;
    414         fmt( is, "%lf%lfi", &re, &im );
    415         dc = re + im * _Complex_I;
    416         return is;
    417 } // ?|?
    418 
    419 forall( dtype istype | istream( istype ) )
    420 istype & ?|?( istype & is, long double _Complex & ldc ) {
    421         long double re, im;
    422         fmt( is, "%Lf%Lfi", &re, &im );
    423         ldc = re + im * _Complex_I;
    424         return is;
    425 } // ?|?
    426 
    427 forall( dtype istype | istream( istype ) )
    428 istype & ?|?( istype & is, istype & (* manip)( istype & ) ) {
    429         return manip( is );
    430 } // ?|?
    431 
    432 forall( dtype istype | istream( istype ) )
    433 istype & endl( istype & is ) {
    434         fmt( is, "%*[ \t\f\n\r\v]" );                                           // ignore whitespace
    435         return is;
    436 } // endl
     276forall( dtype istype | istream( istype ) ) {
     277        istype & ?|?( istype & is, _Bool & b ) {
     278                char val[6];
     279                fmt( is, "%5s", val );
     280                if ( strcmp( val, "true" ) == 0 ) b = true;
     281                else if ( strcmp( val, "false" ) == 0 ) b = false;
     282                else {
     283                        fprintf( stderr, "invalid _Bool constant\n" );
     284                        abort();
     285                } // if
     286                return is;
     287        } // ?|?
     288
     289        istype & ?|?( istype & is, char & c ) {
     290                fmt( is, "%c", &c );                                                    // must pass pointer through varg to fmt
     291                return is;
     292        } // ?|?
     293
     294        istype & ?|?( istype & is, signed char & sc ) {
     295                fmt( is, "%hhd", &sc );
     296                return is;
     297        } // ?|?
     298
     299        istype & ?|?( istype & is, unsigned char & usc ) {
     300                fmt( is, "%hhu", &usc );
     301                return is;
     302        } // ?|?
     303
     304        istype & ?|?( istype & is, short int & si ) {
     305                fmt( is, "%hd", &si );
     306                return is;
     307        } // ?|?
     308
     309        istype & ?|?( istype & is, unsigned short int & usi ) {
     310                fmt( is, "%hu", &usi );
     311                return is;
     312        } // ?|?
     313
     314        istype & ?|?( istype & is, int & i ) {
     315                fmt( is, "%d", &i );
     316                return is;
     317        } // ?|?
     318
     319        istype & ?|?( istype & is, unsigned int & ui ) {
     320                fmt( is, "%u", &ui );
     321                return is;
     322        } // ?|?
     323
     324        istype & ?|?( istype & is, long int & li ) {
     325                fmt( is, "%ld", &li );
     326                return is;
     327        } // ?|?
     328
     329        istype & ?|?( istype & is, unsigned long int & ulli ) {
     330                fmt( is, "%lu", &ulli );
     331                return is;
     332        } // ?|?
     333
     334        istype & ?|?( istype & is, long long int & lli ) {
     335                fmt( is, "%lld", &lli );
     336                return is;
     337        } // ?|?
     338
     339        istype & ?|?( istype & is, unsigned long long int & ulli ) {
     340                fmt( is, "%llu", &ulli );
     341                return is;
     342        } // ?|?
     343
     344
     345        istype & ?|?( istype & is, float & f ) {
     346                fmt( is, "%f", &f );
     347                return is;
     348        } // ?|?
     349
     350        istype & ?|?( istype & is, double & d ) {
     351                fmt( is, "%lf", &d );
     352                return is;
     353        } // ?|?
     354
     355        istype & ?|?( istype & is, long double & ld ) {
     356                fmt( is, "%Lf", &ld );
     357                return is;
     358        } // ?|?
     359
     360
     361        istype & ?|?( istype & is, float _Complex & fc ) {
     362                float re, im;
     363                fmt( is, "%g%gi", &re, &im );
     364                fc = re + im * _Complex_I;
     365                return is;
     366        } // ?|?
     367
     368        istype & ?|?( istype & is, double _Complex & dc ) {
     369                double re, im;
     370                fmt( is, "%lf%lfi", &re, &im );
     371                dc = re + im * _Complex_I;
     372                return is;
     373        } // ?|?
     374
     375        istype & ?|?( istype & is, long double _Complex & ldc ) {
     376                long double re, im;
     377                fmt( is, "%Lf%Lfi", &re, &im );
     378                ldc = re + im * _Complex_I;
     379                return is;
     380        } // ?|?
     381
     382
     383        // manipulators
     384        istype & ?|?( istype & is, istype & (* manip)( istype & ) ) {
     385                return manip( is );
     386        } // ?|?
     387
     388        istype & endl( istype & is ) {
     389                fmt( is, "%*[ \t\f\n\r\v]" );                                   // ignore whitespace
     390                return is;
     391        } // endl
     392} // distribution
    437393
    438394_Istream_cstrUC cstr( char * str ) { return (_Istream_cstrUC){ str }; }
  • src/libcfa/rational

    r0182bfa r28f3a19  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Wed Dec  6 23:12:53 2017
    15 // Update Count     : 97
     14// Last Modified On : Sat Jun  2 09:10:01 2018
     15// Update Count     : 105
    1616//
    1717
     
    4646// implementation
    4747
    48 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    49 struct Rational {
    50         RationalImpl numerator, denominator;                            // invariant: denominator > 0
    51 }; // Rational
     48forall( otype RationalImpl | arithmetic( RationalImpl ) ) {
     49        struct Rational {
     50                RationalImpl numerator, denominator;                    // invariant: denominator > 0
     51        }; // Rational
    5252
    53 // constructors
     53        // constructors
    5454
    55 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    56 void ?{}( Rational(RationalImpl) & r );
     55        void ?{}( Rational(RationalImpl) & r );
     56        void ?{}( Rational(RationalImpl) & r, RationalImpl n );
     57        void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d );
     58        void ?{}( Rational(RationalImpl) & r, zero_t );
     59        void ?{}( Rational(RationalImpl) & r, one_t );
    5760
    58 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    59 void ?{}( Rational(RationalImpl) & r, RationalImpl n );
     61        // numerator/denominator getter
    6062
    61 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    62 void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d );
     63        RationalImpl numerator( Rational(RationalImpl) r );
     64        RationalImpl denominator( Rational(RationalImpl) r );
     65        [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src );
    6366
    64 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    65 void ?{}( Rational(RationalImpl) & r, zero_t );
     67        // numerator/denominator setter
    6668
    67 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    68 void ?{}( Rational(RationalImpl) & r, one_t );
     69        RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n );
     70        RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d );
    6971
    70 // numerator/denominator getter
     72        // comparison
    7173
    72 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    73 RationalImpl numerator( Rational(RationalImpl) r );
     74        int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     75        int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     76        int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     77        int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     78        int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     79        int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    7480
    75 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    76 RationalImpl denominator( Rational(RationalImpl) r );
     81        // arithmetic
    7782
    78 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    79 [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src );
     83        Rational(RationalImpl) +?( Rational(RationalImpl) r );
     84        Rational(RationalImpl) -?( Rational(RationalImpl) r );
     85        Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     86        Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     87        Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     88        Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    8089
    81 // numerator/denominator setter
     90        // I/O
     91        forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
     92        istype & ?|?( istype &, Rational(RationalImpl) & );
    8293
    83 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    84 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n );
    85 
    86 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    87 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d );
    88 
    89 // comparison
    90 
    91 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    92 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    93 
    94 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    95 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    96 
    97 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    98 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    99 
    100 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    101 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    102 
    103 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    104 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    105 
    106 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    107 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    108 
    109 // arithmetic
    110 
    111 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    112 Rational(RationalImpl) +?( Rational(RationalImpl) r );
    113 
    114 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    115 Rational(RationalImpl) -?( Rational(RationalImpl) r );
    116 
    117 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    118 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    119 
    120 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    121 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    122 
    123 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    124 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    125 
    126 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    127 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     94        forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } )
     95        ostype & ?|?( ostype &, Rational(RationalImpl ) );
     96} // distribution
    12897
    12998// conversion
     
    133102Rational(RationalImpl) narrow( double f, RationalImpl md );
    134103
    135 // I/O
    136 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    137 forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
    138 istype & ?|?( istype &, Rational(RationalImpl) & );
    139 
    140 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    141 forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } )
    142 ostype & ?|?( ostype &, Rational(RationalImpl ) );
    143 
    144104// Local Variables: //
    145105// mode: c //
  • src/libcfa/rational.c

    r0182bfa r28f3a19  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Dec  6 23:13:58 2017
    13 // Update Count     : 156
     12// Last Modified On : Sat Jun  2 09:24:33 2018
     13// Update Count     : 162
    1414//
    1515
     
    1818#include "stdlib"
    1919
    20 // helper routines
    21 
    22 // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals.
    23 // alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    24 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    25 static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
    26         for ( ;; ) {                                                                            // Euclid's algorithm
    27                 RationalImpl r = a % b;
    28           if ( r == (RationalImpl){0} ) break;
    29                 a = b;
    30                 b = r;
    31         } // for
    32         return b;
    33 } // gcd
    34 
    35 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    36 static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
    37         if ( d == (RationalImpl){0} ) {
    38                 serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl;
    39                 exit( EXIT_FAILURE );
    40         } // exit
    41         if ( d < (RationalImpl){0} ) { d = -d; n = -n; }        // move sign to numerator
    42         return gcd( abs( n ), d );                                                      // simplify
    43 } // Rationalnumber::simplify
    44 
    45 
    46 // constructors
    47 
    48 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    49 void ?{}( Rational(RationalImpl) & r ) {
    50         r{ (RationalImpl){0}, (RationalImpl){1} };
    51 } // rational
    52 
    53 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    54 void ?{}( Rational(RationalImpl) & r, RationalImpl n ) {
    55         r{ n, (RationalImpl){1} };
    56 } // rational
    57 
    58 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    59 void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
    60         RationalImpl t = simplify( n, d );                                      // simplify
    61         r.numerator = n / t;
    62         r.denominator = d / t;
    63 } // rational
    64 
    65 
    66 // getter for numerator/denominator
    67 
    68 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    69 RationalImpl numerator( Rational(RationalImpl) r ) {
    70         return r.numerator;
    71 } // numerator
    72 
    73 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    74 RationalImpl denominator( Rational(RationalImpl) r ) {
    75         return r.denominator;
    76 } // denominator
    77 
    78 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    79 [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) {
    80         return dest = src.[ numerator, denominator ];
    81 }
    82 
    83 // setter for numerator/denominator
    84 
    85 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    86 RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) {
    87         RationalImpl prev = r.numerator;
    88         RationalImpl t = gcd( abs( n ), r.denominator );                // simplify
    89         r.numerator = n / t;
    90         r.denominator = r.denominator / t;
    91         return prev;
    92 } // numerator
    93 
    94 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    95 RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) {
    96         RationalImpl prev = r.denominator;
    97         RationalImpl t = simplify( r.numerator, d );                    // simplify
    98         r.numerator = r.numerator / t;
    99         r.denominator = d / t;
    100         return prev;
    101 } // denominator
    102 
    103 
    104 // comparison
    105 
    106 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    107 int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    108         return l.numerator * r.denominator == l.denominator * r.numerator;
    109 } // ?==?
    110 
    111 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    112 int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    113         return ! ( l == r );
    114 } // ?!=?
    115 
    116 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    117 int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    118         return l.numerator * r.denominator < l.denominator * r.numerator;
    119 } // ?<?
    120 
    121 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    122 int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    123         return l.numerator * r.denominator <= l.denominator * r.numerator;
    124 } // ?<=?
    125 
    126 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    127 int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    128         return ! ( l <= r );
    129 } // ?>?
    130 
    131 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    132 int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    133         return ! ( l < r );
    134 } // ?>=?
    135 
    136 
    137 // arithmetic
    138 
    139 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    140 Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
    141         Rational(RationalImpl) t = { r.numerator, r.denominator };
    142         return t;
    143 } // +?
    144 
    145 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    146 Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
    147         Rational(RationalImpl) t = { -r.numerator, r.denominator };
    148         return t;
    149 } // -?
    150 
    151 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    152 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    153         if ( l.denominator == r.denominator ) {                         // special case
    154                 Rational(RationalImpl) t = { l.numerator + r.numerator, l.denominator };
    155                 return t;
    156         } else {
    157                 Rational(RationalImpl) t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
    158                 return t;
    159         } // if
    160 } // ?+?
    161 
    162 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    163 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    164         if ( l.denominator == r.denominator ) {                         // special case
    165                 Rational(RationalImpl) t = { l.numerator - r.numerator, l.denominator };
    166                 return t;
    167         } else {
    168                 Rational(RationalImpl) t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
    169                 return t;
    170         } // if
    171 } // ?-?
    172 
    173 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    174 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    175         Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator };
    176         return t;
    177 } // ?*?
    178 
    179 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    180 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    181         if ( r.numerator < (RationalImpl){0} ) {
    182                 r.numerator = -r.numerator;
    183                 r.denominator = -r.denominator;
    184         } // if
    185         Rational(RationalImpl) t = { l.numerator * r.denominator, l.denominator * r.numerator };
    186         return t;
    187 } // ?/?
    188 
     20forall( otype RationalImpl | arithmetic( RationalImpl ) ) {
     21        // helper routines
     22
     23        // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce
     24        // rationals.  alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
     25        static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
     26                for ( ;; ) {                                                                    // Euclid's algorithm
     27                        RationalImpl r = a % b;
     28                  if ( r == (RationalImpl){0} ) break;
     29                        a = b;
     30                        b = r;
     31                } // for
     32                return b;
     33        } // gcd
     34
     35        static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
     36                if ( d == (RationalImpl){0} ) {
     37                        serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl;
     38                        exit( EXIT_FAILURE );
     39                } // exit
     40                if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
     41                return gcd( abs( n ), d );                                              // simplify
     42        } // Rationalnumber::simplify
     43
     44        // constructors
     45
     46        void ?{}( Rational(RationalImpl) & r ) {
     47                r{ (RationalImpl){0}, (RationalImpl){1} };
     48        } // rational
     49
     50        void ?{}( Rational(RationalImpl) & r, RationalImpl n ) {
     51                r{ n, (RationalImpl){1} };
     52        } // rational
     53
     54        void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
     55                RationalImpl t = simplify( n, d );                              // simplify
     56                r.numerator = n / t;
     57                r.denominator = d / t;
     58        } // rational
     59
     60
     61        // getter for numerator/denominator
     62
     63        RationalImpl numerator( Rational(RationalImpl) r ) {
     64                return r.numerator;
     65        } // numerator
     66
     67        RationalImpl denominator( Rational(RationalImpl) r ) {
     68                return r.denominator;
     69        } // denominator
     70
     71        [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) {
     72                return dest = src.[ numerator, denominator ];
     73        } // ?=?
     74
     75        // setter for numerator/denominator
     76
     77        RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) {
     78                RationalImpl prev = r.numerator;
     79                RationalImpl t = gcd( abs( n ), r.denominator ); // simplify
     80                r.numerator = n / t;
     81                r.denominator = r.denominator / t;
     82                return prev;
     83        } // numerator
     84
     85        RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) {
     86                RationalImpl prev = r.denominator;
     87                RationalImpl t = simplify( r.numerator, d );    // simplify
     88                r.numerator = r.numerator / t;
     89                r.denominator = d / t;
     90                return prev;
     91        } // denominator
     92
     93        // comparison
     94
     95        int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     96                return l.numerator * r.denominator == l.denominator * r.numerator;
     97        } // ?==?
     98
     99        int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     100                return ! ( l == r );
     101        } // ?!=?
     102
     103        int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     104                return l.numerator * r.denominator < l.denominator * r.numerator;
     105        } // ?<?
     106
     107        int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     108                return l.numerator * r.denominator <= l.denominator * r.numerator;
     109        } // ?<=?
     110
     111        int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     112                return ! ( l <= r );
     113        } // ?>?
     114
     115        int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     116                return ! ( l < r );
     117        } // ?>=?
     118
     119        // arithmetic
     120
     121        Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
     122                Rational(RationalImpl) t = { r.numerator, r.denominator };
     123                return t;
     124        } // +?
     125
     126        Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
     127                Rational(RationalImpl) t = { -r.numerator, r.denominator };
     128                return t;
     129        } // -?
     130
     131        Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     132                if ( l.denominator == r.denominator ) {                 // special case
     133                        Rational(RationalImpl) t = { l.numerator + r.numerator, l.denominator };
     134                        return t;
     135                } else {
     136                        Rational(RationalImpl) t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
     137                        return t;
     138                } // if
     139        } // ?+?
     140
     141        Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     142                if ( l.denominator == r.denominator ) {                 // special case
     143                        Rational(RationalImpl) t = { l.numerator - r.numerator, l.denominator };
     144                        return t;
     145                } else {
     146                        Rational(RationalImpl) t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
     147                        return t;
     148                } // if
     149        } // ?-?
     150
     151        Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     152                Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator };
     153                return t;
     154        } // ?*?
     155
     156        Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     157                if ( r.numerator < (RationalImpl){0} ) {
     158                        r.numerator = -r.numerator;
     159                        r.denominator = -r.denominator;
     160                } // if
     161                Rational(RationalImpl) t = { l.numerator * r.denominator, l.denominator * r.numerator };
     162                return t;
     163        } // ?/?
     164
     165        // I/O
     166
     167        forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
     168        istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
     169                RationalImpl t;
     170                is | r.numerator | r.denominator;
     171                t = simplify( r.numerator, r.denominator );
     172                r.numerator /= t;
     173                r.denominator /= t;
     174                return is;
     175        } // ?|?
     176
     177        forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } )
     178        ostype & ?|?( ostype & os, Rational(RationalImpl ) r ) {
     179                return os | r.numerator | '/' | r.denominator;
     180        } // ?|?
     181} // distribution
    189182
    190183// conversion
     
    195188} // widen
    196189
    197 // http://www.ics.uci.edu/~eppstein/numth/frap.c
    198190forall( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
    199191Rational(RationalImpl) narrow( double f, RationalImpl md ) {
     192        // http://www.ics.uci.edu/~eppstein/numth/frap.c
    200193        if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
    201194                return (Rational(RationalImpl)){ convert( f ), (RationalImpl){1}}; // truncate fraction
     
    224217} // narrow
    225218
    226 
    227 // I/O
    228 
    229 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    230 forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
    231 istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
    232         RationalImpl t;
    233         is | r.numerator | r.denominator;
    234         t = simplify( r.numerator, r.denominator );
    235         r.numerator /= t;
    236         r.denominator /= t;
    237         return is;
    238 } // ?|?
    239 
    240 forall( otype RationalImpl | arithmetic( RationalImpl ) )
    241 forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } )
    242 ostype & ?|?( ostype & os, Rational(RationalImpl ) r ) {
    243         return os | r.numerator | '/' | r.denominator;
    244 } // ?|?
    245 
    246219// Local Variables: //
    247220// tab-width: 4 //
  • src/libcfa/stdhdr/assert.h

    r0182bfa r28f3a19  
    3333        #define verify(x) assert(x)
    3434        #define verifyf(x, ...) assertf(x, __VA_ARGS__)
     35        #define __CFA_WITH_VERIFY__
    3536#else
    3637        #define verify(x)
  • src/libcfa/stdlib

    r0182bfa r28f3a19  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 16 07:53:10 2018
    13 // Update Count     : 300
     12// Last Modified On : Sat Jun  2 08:46:35 2018
     13// Update Count     : 306
    1414//
    1515
    1616#pragma once
    1717
    18 #include <stdlib.h>                                                                             // strto*, *abs
     18#include <stdlib.h>                                                                             // allocation, strto*, *abs
     19extern "C" {
     20        void * memalign( size_t align, size_t size );
     21        void * aligned_alloc( size_t align, size_t size );
     22        void * memset( void * dest, int c, size_t size );
     23} // extern "C"
    1924
    2025//---------------------------------------
     
    2732//---------------------------------------
    2833
    29 // C dynamic allocation
    3034static inline forall( dtype T | sized(T) ) {
     35        // C dynamic allocation
     36
    3137        T * malloc( void ) {
    3238                // printf( "* malloc\n" );
     
    5157        } // realloc
    5258
    53         extern "C" { void * memalign( size_t align, size_t size ); } // use default C routine for void *
    5459        T * memalign( size_t align ) {
    5560                //printf( "X4\n" );
     
    5762        } // memalign
    5863
    59         extern "C" { void * aligned_alloc( size_t align, size_t size ); } // use default C routine for void *
    6064        T * aligned_alloc( size_t align ) {
    6165                //printf( "X5\n" );
     
    7074
    7175        // Cforall dynamic allocation
    72         extern "C" { void * memset( void * dest, int c, size_t size ); } // use default C routine for void *
    7376
    7477        T * alloc( void ) {
     
    103106forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill );
    104107
    105 static inline forall( dtype T | sized(T) ) T * align_alloc( size_t align ) {
    106         //printf( "X13\n" );
    107         return (T *)memalign( align, sizeof(T) );
    108 } // align_alloc
    109 static inline forall( dtype T | sized(T) ) T * align_alloc( size_t align, char fill ) {
    110         //printf( "X14\n" );
    111     T * ptr = (T *)memalign( align, sizeof(T) );
    112     return (T *)memset( ptr, (int)fill, sizeof(T) );
    113 } // align_alloc
    114 
    115 static inline forall( dtype T | sized(T) ) T * align_alloc( size_t align, size_t dim ) {
    116         //printf( "X15\n" );
    117         return (T *)memalign( align, dim * sizeof(T) );
    118 } // align_alloc
    119 static inline forall( dtype T | sized(T) ) T * align_alloc( size_t align, size_t dim, char fill ) {
    120         //printf( "X16\n" );
    121     T * ptr = (T *)memalign( align, dim * sizeof(T) );
    122     return (T *)memset( ptr, (int)fill, dim * sizeof(T) );
    123 } // align_alloc
    124 
    125 
    126 // data, non-array types
    127 static inline forall( dtype T | sized(T) ) T * memset( T * dest, char c ) {
    128         //printf( "X17\n" );
    129         return (T *)memset( dest, c, sizeof(T) );
    130 } // memset
    131 extern "C" { void * memcpy( void * dest, const void * src, size_t size ); } // use default C routine for void *
    132 static inline forall( dtype T | sized(T) ) T * memcpy( T * dest, const T * src ) {
    133         //printf( "X18\n" );
    134         return (T *)memcpy( dest, src, sizeof(T) );
    135 } // memcpy
    136 
    137 // data, array types
    138 static inline forall( dtype T | sized(T) ) T * memset( T dest[], size_t dim, char c ) {
    139         //printf( "X19\n" );
    140         return (T *)(void *)memset( dest, c, dim * sizeof(T) ); // C memset
    141 } // memset
    142 static inline forall( dtype T | sized(T) ) T * memcpy( T dest[], const T src[], size_t dim ) {
    143         //printf( "X20\n" );
    144         return (T *)(void *)memcpy( dest, src, dim * sizeof(T) ); // C memcpy
    145 } // memcpy
     108
     109static inline forall( dtype T | sized(T) ) {
     110        T * align_alloc( size_t align ) {
     111                //printf( "X13\n" );
     112                return (T *)memalign( align, sizeof(T) );
     113        } // align_alloc
     114
     115        T * align_alloc( size_t align, char fill ) {
     116                //printf( "X14\n" );
     117                T * ptr = (T *)memalign( align, sizeof(T) );
     118                return (T *)memset( ptr, (int)fill, sizeof(T) );
     119        } // align_alloc
     120
     121        T * align_alloc( size_t align, size_t dim ) {
     122                //printf( "X15\n" );
     123                return (T *)memalign( align, dim * sizeof(T) );
     124        } // align_alloc
     125
     126        T * align_alloc( size_t align, size_t dim, char fill ) {
     127                //printf( "X16\n" );
     128                T * ptr = (T *)memalign( align, dim * sizeof(T) );
     129                return (T *)memset( ptr, (int)fill, dim * sizeof(T) );
     130        } // align_alloc
     131} // distribution
     132
     133
     134static inline forall( dtype T | sized(T) ) {
     135        // data, non-array types
     136
     137        T * memset( T * dest, char c ) {
     138                //printf( "X17\n" );
     139                return (T *)memset( dest, c, sizeof(T) );
     140        } // memset
     141
     142        extern "C" { void * memcpy( void * dest, const void * src, size_t size ); } // use default C routine for void *
     143
     144        T * memcpy( T * dest, const T * src ) {
     145                //printf( "X18\n" );
     146                return (T *)memcpy( dest, src, sizeof(T) );
     147        } // memcpy
     148} // distribution
     149
     150static inline forall( dtype T | sized(T) ) {
     151        // data, array types
     152
     153        T * memset( T dest[], size_t dim, char c ) {
     154                //printf( "X19\n" );
     155                return (T *)(void *)memset( dest, c, dim * sizeof(T) ); // C memset
     156        } // memset
     157
     158        T * memcpy( T dest[], const T src[], size_t dim ) {
     159                //printf( "X20\n" );
     160                return (T *)(void *)memcpy( dest, src, dim * sizeof(T) ); // C memcpy
     161        } // memcpy
     162} // distribution
    146163
    147164// allocation/deallocation and constructor/destructor, non-array types
     
    189206//---------------------------------------
    190207
    191 forall( otype E | { int ?<?( E, E ); } )
    192 E * bsearch( E key, const E * vals, size_t dim );
    193 
    194 forall( otype E | { int ?<?( E, E ); } )
    195 size_t bsearch( E key, const E * vals, size_t dim );
    196 
    197 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    198 E * bsearch( K key, const E * vals, size_t dim );
    199 
    200 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    201 size_t bsearch( K key, const E * vals, size_t dim );
    202 
    203 
    204 forall( otype E | { int ?<?( E, E ); } )
    205 E * bsearchl( E key, const E * vals, size_t dim );
    206 
    207 forall( otype E | { int ?<?( E, E ); } )
    208 size_t bsearchl( E key, const E * vals, size_t dim );
    209 
    210 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    211 E * bsearchl( K key, const E * vals, size_t dim );
    212 
    213 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    214 size_t bsearchl( K key, const E * vals, size_t dim );
    215 
    216 
    217 forall( otype E | { int ?<?( E, E ); } )
    218 E * bsearchu( E key, const E * vals, size_t dim );
    219 
    220 forall( otype E | { int ?<?( E, E ); } )
    221 size_t bsearchu( E key, const E * vals, size_t dim );
    222 
    223 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    224 E * bsearchu( K key, const E * vals, size_t dim );
    225 
    226 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    227 size_t bsearchu( K key, const E * vals, size_t dim );
    228 
    229 
    230 forall( otype E | { int ?<?( E, E ); } )
    231 void qsort( E * vals, size_t dim );
     208forall( otype E | { int ?<?( E, E ); } ) {
     209        E * bsearch( E key, const E * vals, size_t dim );
     210        size_t bsearch( E key, const E * vals, size_t dim );
     211        E * bsearchl( E key, const E * vals, size_t dim );
     212        size_t bsearchl( E key, const E * vals, size_t dim );
     213        E * bsearchu( E key, const E * vals, size_t dim );
     214        size_t bsearchu( E key, const E * vals, size_t dim );
     215
     216        void qsort( E * vals, size_t dim );
     217} // distribution
     218
     219forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } ) {
     220        E * bsearch( K key, const E * vals, size_t dim );
     221        size_t bsearch( K key, const E * vals, size_t dim );
     222        E * bsearchl( K key, const E * vals, size_t dim );
     223        size_t bsearchl( K key, const E * vals, size_t dim );
     224        E * bsearchu( K key, const E * vals, size_t dim );
     225        size_t bsearchu( K key, const E * vals, size_t dim );
     226} // distribution
    232227
    233228//---------------------------------------
  • src/libcfa/stdlib.c

    r0182bfa r28f3a19  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan  3 08:29:29 2018
    13 // Update Count     : 444
     12// Last Modified On : Sat Jun  2 06:15:05 2018
     13// Update Count     : 448
    1414//
    1515
     
    130130//---------------------------------------
    131131
    132 forall( otype E | { int ?<?( E, E ); } )
    133 E * bsearch( E key, const E * vals, size_t dim ) {
    134         int cmp( const void * t1, const void * t2 ) {
    135                 return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
    136         } // cmp
    137         return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
    138 } // bsearch
    139 
    140 forall( otype E | { int ?<?( E, E ); } )
    141 size_t bsearch( E key, const E * vals, size_t dim ) {
    142         E * result = bsearch( key, vals, dim );
    143         return result ? result - vals : dim;                            // pointer subtraction includes sizeof(E)
    144 } // bsearch
    145 
    146 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    147 E * bsearch( K key, const E * vals, size_t dim ) {
    148         int cmp( const void * t1, const void * t2 ) {
    149                 return *(K *)t1 < getKey( *(E *)t2 ) ? -1 : getKey( *(E *)t2 ) < *(K *)t1 ? 1 : 0;
    150         } // cmp
    151         return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
    152 } // bsearch
    153 
    154 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    155 size_t bsearch( K key, const E * vals, size_t dim ) {
    156         E * result = bsearch( key, vals, dim );
    157         return result ? result - vals : dim;                            // pointer subtraction includes sizeof(E)
    158 } // bsearch
    159 
    160 
    161 forall( otype E | { int ?<?( E, E ); } )
    162 size_t bsearchl( E key, const E * vals, size_t dim ) {
    163         size_t l = 0, m, h = dim;
    164         while ( l < h ) {
    165                 m = (l + h) / 2;
    166                 if ( (E &)(vals[m]) < key ) {                                   // cast away const
    167                         l = m + 1;
    168                 } else {
    169                         h = m;
    170                 } // if
    171         } // while
    172         return l;
    173 } // bsearchl
    174 
    175 forall( otype E | { int ?<?( E, E ); } )
    176 E * bsearchl( E key, const E * vals, size_t dim ) {
    177         size_t posn = bsearchl( key, vals, dim );
    178         return (E *)(&vals[posn]);                                                      // cast away const
    179 } // bsearchl
    180 
    181 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    182 size_t bsearchl( K key, const E * vals, size_t dim ) {
    183         size_t l = 0, m, h = dim;
    184         while ( l < h ) {
    185                 m = (l + h) / 2;
    186                 if ( getKey( vals[m] ) < key ) {
    187                         l = m + 1;
    188                 } else {
    189                         h = m;
    190                 } // if
    191         } // while
    192         return l;
    193 } // bsearchl
    194 
    195 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    196 E * bsearchl( K key, const E * vals, size_t dim ) {
    197         size_t posn = bsearchl( key, vals, dim );
    198         return (E *)(&vals[posn]);                                                      // cast away const
    199 } // bsearchl
    200 
    201 
    202 forall( otype E | { int ?<?( E, E ); } )
    203 size_t bsearchu( E key, const E * vals, size_t dim ) {
    204         size_t l = 0, m, h = dim;
    205         while ( l < h ) {
    206                 m = (l + h) / 2;
    207                 if ( ! ( key < (E &)(vals[m]) ) ) {                             // cast away const
    208                         l = m + 1;
    209                 } else {
    210                         h = m;
    211                 } // if
    212         } // while
    213         return l;
    214 } // bsearchu
    215 
    216 forall( otype E | { int ?<?( E, E ); } )
    217 E * bsearchu( E key, const E * vals, size_t dim ) {
    218         size_t posn = bsearchu( key, vals, dim );
    219         return (E *)(&vals[posn]);
    220 } // bsearchu
    221 
    222 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    223 size_t bsearchu( K key, const E * vals, size_t dim ) {
    224         size_t l = 0, m, h = dim;
    225         while ( l < h ) {
    226                 m = (l + h) / 2;
    227                 if ( ! ( key < getKey( vals[m] ) ) ) {
    228                         l = m + 1;
    229                 } else {
    230                         h = m;
    231                 } // if
    232         } // while
    233         return l;
    234 } // bsearchu
    235 
    236 forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } )
    237 E * bsearchu( K key, const E * vals, size_t dim ) {
    238         size_t posn = bsearchu( key, vals, dim );
    239         return (E *)(&vals[posn]);
    240 } // bsearchu
    241 
    242 
    243 forall( otype E | { int ?<?( E, E ); } )
    244 void qsort( E * vals, size_t dim ) {
    245         int cmp( const void * t1, const void * t2 ) {
    246                 return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
    247         } // cmp
    248         qsort( vals, dim, sizeof(E), cmp );
    249 } // qsort
     132forall( otype E | { int ?<?( E, E ); } ) {
     133        E * bsearch( E key, const E * vals, size_t dim ) {
     134                int cmp( const void * t1, const void * t2 ) {
     135                        return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
     136                } // cmp
     137                return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
     138        } // bsearch
     139
     140        size_t bsearch( E key, const E * vals, size_t dim ) {
     141                E * result = bsearch( key, vals, dim );
     142                return result ? result - vals : dim;                    // pointer subtraction includes sizeof(E)
     143        } // bsearch
     144
     145        size_t bsearchl( E key, const E * vals, size_t dim ) {
     146                size_t l = 0, m, h = dim;
     147                while ( l < h ) {
     148                        m = (l + h) / 2;
     149                        if ( (E &)(vals[m]) < key ) {                           // cast away const
     150                                l = m + 1;
     151                        } else {
     152                                h = m;
     153                        } // if
     154                } // while
     155                return l;
     156        } // bsearchl
     157
     158        E * bsearchl( E key, const E * vals, size_t dim ) {
     159                size_t posn = bsearchl( key, vals, dim );
     160                return (E *)(&vals[posn]);                                              // cast away const
     161        } // bsearchl
     162
     163        size_t bsearchu( E key, const E * vals, size_t dim ) {
     164                size_t l = 0, m, h = dim;
     165                while ( l < h ) {
     166                        m = (l + h) / 2;
     167                        if ( ! ( key < (E &)(vals[m]) ) ) {                     // cast away const
     168                                l = m + 1;
     169                        } else {
     170                                h = m;
     171                        } // if
     172                } // while
     173                return l;
     174        } // bsearchu
     175
     176        E * bsearchu( E key, const E * vals, size_t dim ) {
     177                size_t posn = bsearchu( key, vals, dim );
     178                return (E *)(&vals[posn]);
     179        } // bsearchu
     180
     181
     182        void qsort( E * vals, size_t dim ) {
     183                int cmp( const void * t1, const void * t2 ) {
     184                        return *(E *)t1 < *(E *)t2 ? -1 : *(E *)t2 < *(E *)t1 ? 1 : 0;
     185                } // cmp
     186                qsort( vals, dim, sizeof(E), cmp );
     187        } // qsort
     188} // distribution
     189
     190
     191forall( otype K, otype E | { int ?<?( K, K ); K getKey( const E & ); } ) {
     192        E * bsearch( K key, const E * vals, size_t dim ) {
     193                int cmp( const void * t1, const void * t2 ) {
     194                        return *(K *)t1 < getKey( *(E *)t2 ) ? -1 : getKey( *(E *)t2 ) < *(K *)t1 ? 1 : 0;
     195                } // cmp
     196                return (E *)bsearch( &key, vals, dim, sizeof(E), cmp );
     197        } // bsearch
     198
     199        size_t bsearch( K key, const E * vals, size_t dim ) {
     200                E * result = bsearch( key, vals, dim );
     201                return result ? result - vals : dim;                    // pointer subtraction includes sizeof(E)
     202        } // bsearch
     203
     204        size_t bsearchl( K key, const E * vals, size_t dim ) {
     205                size_t l = 0, m, h = dim;
     206                while ( l < h ) {
     207                        m = (l + h) / 2;
     208                        if ( getKey( vals[m] ) < key ) {
     209                                l = m + 1;
     210                        } else {
     211                                h = m;
     212                        } // if
     213                } // while
     214                return l;
     215        } // bsearchl
     216
     217        E * bsearchl( K key, const E * vals, size_t dim ) {
     218                size_t posn = bsearchl( key, vals, dim );
     219                return (E *)(&vals[posn]);                                              // cast away const
     220        } // bsearchl
     221
     222        size_t bsearchu( K key, const E * vals, size_t dim ) {
     223                size_t l = 0, m, h = dim;
     224                while ( l < h ) {
     225                        m = (l + h) / 2;
     226                        if ( ! ( key < getKey( vals[m] ) ) ) {
     227                                l = m + 1;
     228                        } else {
     229                                h = m;
     230                        } // if
     231                } // while
     232                return l;
     233        } // bsearchu
     234
     235        E * bsearchu( K key, const E * vals, size_t dim ) {
     236                size_t posn = bsearchu( key, vals, dim );
     237                return (E *)(&vals[posn]);
     238        } // bsearchu
     239} // distribution
    250240
    251241//---------------------------------------
  • src/main.cc

    r0182bfa r28f3a19  
    1111// Created On       : Fri May 15 23:12:02 2015
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Mon May  7 14:35:57 2018
    14 // Update Count     : 492
     13// Last Modified On : Wed Jun  6 15:51:47 2018
     14// Update Count     : 498
    1515//
    1616
     
    160160                 << "." << endl;
    161161        backtrace( 2 );                                                                         // skip first 2 stack frames
    162         exit( EXIT_FAILURE );
     162        //_exit( EXIT_FAILURE );
     163        abort();
    163164} // sigSegvBusHandler
    164165
     
    261262                } // if
    262263
    263                 PASS( "mutate", ControlStruct::mutate( translationUnit ) );
     264                PASS( "fixLabels", ControlStruct::fixLabels( translationUnit ) );
    264265                PASS( "fixNames", CodeGen::fixNames( translationUnit ) );
    265266                PASS( "genInit", InitTweak::genInit( translationUnit ) );
     
    571572        yyin = input;
    572573        yylineno = 1;
    573         typedefTable.enterScope();
    574574        int parseStatus = yyparse();
    575575
  • src/prelude/Makefile.am

    r0182bfa r28f3a19  
    3737# create forward declarations for gcc builtins
    3838gcc-builtins.cf : gcc-builtins.c prototypes.sed
    39         ${AM_V_GEN}@BACKEND_CC@ -E -P $< | sed -r -f prototypes.sed > $@
     39        ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E -P $< | sed -r -f prototypes.sed > $@
    4040
    4141gcc-builtins.c : builtins.def prototypes.awk sync-builtins.cf
    42         ${AM_V_GEN}@BACKEND_CC@ -E prototypes.c | awk -f prototypes.awk > $@
     42        ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E prototypes.c | awk -f prototypes.awk > $@
    4343
    4444builtins.def :
  • src/prelude/Makefile.in

    r0182bfa r28f3a19  
    506506# create forward declarations for gcc builtins
    507507gcc-builtins.cf : gcc-builtins.c prototypes.sed
    508         ${AM_V_GEN}@BACKEND_CC@ -E -P $< | sed -r -f prototypes.sed > $@
     508        ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E -P $< | sed -r -f prototypes.sed > $@
    509509
    510510gcc-builtins.c : builtins.def prototypes.awk sync-builtins.cf
    511         ${AM_V_GEN}@BACKEND_CC@ -E prototypes.c | awk -f prototypes.awk > $@
     511        ${AM_V_GEN}@BACKEND_CC@ @CFA_FLAGS@ -E prototypes.c | awk -f prototypes.awk > $@
    512512
    513513builtins.def :
  • src/prelude/extras.regx

    r0182bfa r28f3a19  
    11typedef.* size_t;
    22typedef.* ptrdiff_t;
     3typedef.* __int8_t;
     4typedef.* __int16_t;
     5typedef.* __int32_t;
     6typedef.* __int64_t;
     7typedef.* __uint8_t;
     8typedef.* __uint16_t;
     9typedef.* __uint32_t;
     10typedef.* __uint64_t;
    311typedef.* int8_t;
    412typedef.* int16_t;
  • src/prelude/prelude.cf

    r0182bfa r28f3a19  
    458458signed long long int    ?=?( signed long long int &, signed long long int ),    ?=?( volatile signed long long int &, signed long long int );
    459459unsigned long long int  ?=?( unsigned long long int &, unsigned long long int ), ?=?( volatile unsigned long long int &, unsigned long long int );
    460 __int128        ?=?( __int128 &, __int128 ),    ?=?( volatile __int128 &, __int128 );
    461460zero_t                  ?=?( zero_t &, zero_t );
    462461one_t                   ?=?( one_t &, one_t );
  • src/prelude/sync-builtins.cf

    r0182bfa r28f3a19  
    77long long int __sync_fetch_and_add(volatile long long int *, long long int,...);
    88long long int __sync_fetch_and_add_8(volatile long long int *, long long int,...);
     9#if defined(__SIZEOF_INT128__)
    910__int128 __sync_fetch_and_add(volatile __int128 *, __int128,...);
    1011__int128 __sync_fetch_and_add_16(volatile __int128 *, __int128,...);
     12#endif
    1113
    1214char __sync_fetch_and_sub(volatile char *, char,...);
     
    1820long long int __sync_fetch_and_sub(volatile long long int *, long long int,...);
    1921long long int __sync_fetch_and_sub_8(volatile long long int *, long long int,...);
     22#if defined(__SIZEOF_INT128__)
    2023__int128 __sync_fetch_and_sub(volatile __int128 *, __int128,...);
    2124__int128 __sync_fetch_and_sub_16(volatile __int128 *, __int128,...);
     25#endif
    2226
    2327char __sync_fetch_and_or(volatile char *, char,...);
     
    2933long long int __sync_fetch_and_or(volatile long long int *, long long int,...);
    3034long long int __sync_fetch_and_or_8(volatile long long int *, long long int,...);
     35#if defined(__SIZEOF_INT128__)
    3136__int128 __sync_fetch_and_or(volatile __int128 *, __int128,...);
    3237__int128 __sync_fetch_and_or_16(volatile __int128 *, __int128,...);
     38#endif
    3339
    3440char __sync_fetch_and_and(volatile char *, char,...);
     
    4046long long int __sync_fetch_and_and(volatile long long int *, long long int,...);
    4147long long int __sync_fetch_and_and_8(volatile long long int *, long long int,...);
     48#if defined(__SIZEOF_INT128__)
    4249__int128 __sync_fetch_and_and(volatile __int128 *, __int128,...);
    4350__int128 __sync_fetch_and_and_16(volatile __int128 *, __int128,...);
     51#endif
    4452
    4553char __sync_fetch_and_xor(volatile char *, char,...);
     
    5159long long int __sync_fetch_and_xor(volatile long long int *, long long int,...);
    5260long long int __sync_fetch_and_xor_8(volatile long long int *, long long int,...);
     61#if defined(__SIZEOF_INT128__)
    5362__int128 __sync_fetch_and_xor(volatile __int128 *, __int128,...);
    5463__int128 __sync_fetch_and_xor_16(volatile __int128 *, __int128,...);
     64#endif
    5565
    5666char __sync_fetch_and_nand(volatile char *, char,...);
     
    6272long long int __sync_fetch_and_nand(volatile long long int *, long long int,...);
    6373long long int __sync_fetch_and_nand_8(volatile long long int *, long long int,...);
     74#if defined(__SIZEOF_INT128__)
    6475__int128 __sync_fetch_and_nand(volatile __int128 *, __int128,...);
    6576__int128 __sync_fetch_and_nand_16(volatile __int128 *, __int128,...);
     77#endif
    6678
    6779char __sync_add_and_fetch(volatile char *, char,...);
     
    7385long long int __sync_add_and_fetch(volatile long long int *, long long int,...);
    7486long long int __sync_add_and_fetch_8(volatile long long int *, long long int,...);
     87#if defined(__SIZEOF_INT128__)
    7588__int128 __sync_add_and_fetch(volatile __int128 *, __int128,...);
    7689__int128 __sync_add_and_fetch_16(volatile __int128 *, __int128,...);
     90#endif
    7791
    7892char __sync_sub_and_fetch(volatile char *, char,...);
     
    8498long long int __sync_sub_and_fetch(volatile long long int *, long long int,...);
    8599long long int __sync_sub_and_fetch_8(volatile long long int *, long long int,...);
     100#if defined(__SIZEOF_INT128__)
    86101__int128 __sync_sub_and_fetch(volatile __int128 *, __int128,...);
    87102__int128 __sync_sub_and_fetch_16(volatile __int128 *, __int128,...);
     103#endif
    88104
    89105char __sync_or_and_fetch(volatile char *, char,...);
     
    95111long long int __sync_or_and_fetch(volatile long long int *, long long int,...);
    96112long long int __sync_or_and_fetch_8(volatile long long int *, long long int,...);
     113#if defined(__SIZEOF_INT128__)
    97114__int128 __sync_or_and_fetch(volatile __int128 *, __int128,...);
    98115__int128 __sync_or_and_fetch_16(volatile __int128 *, __int128,...);
     116#endif
    99117
    100118char __sync_and_and_fetch(volatile char *, char,...);
     
    106124long long int __sync_and_and_fetch(volatile long long int *, long long int,...);
    107125long long int __sync_and_and_fetch_8(volatile long long int *, long long int,...);
     126#if defined(__SIZEOF_INT128__)
    108127__int128 __sync_and_and_fetch(volatile __int128 *, __int128,...);
    109128__int128 __sync_and_and_fetch_16(volatile __int128 *, __int128,...);
     129#endif
    110130
    111131char __sync_xor_and_fetch(volatile char *, char,...);
     
    117137long long int __sync_xor_and_fetch(volatile long long int *, long long int,...);
    118138long long int __sync_xor_and_fetch_8(volatile long long int *, long long int,...);
     139#if defined(__SIZEOF_INT128__)
    119140__int128 __sync_xor_and_fetch(volatile __int128 *, __int128,...);
    120141__int128 __sync_xor_and_fetch_16(volatile __int128 *, __int128,...);
     142#endif
    121143
    122144char __sync_nand_and_fetch(volatile char *, char,...);
     
    128150long long int __sync_nand_and_fetch(volatile long long int *, long long int,...);
    129151long long int __sync_nand_and_fetch_8(volatile long long int *, long long int,...);
     152#if defined(__SIZEOF_INT128__)
    130153__int128 __sync_nand_and_fetch(volatile __int128 *, __int128,...);
    131154__int128 __sync_nand_and_fetch_16(volatile __int128 *, __int128,...);
     155#endif
    132156
    133157_Bool __sync_bool_compare_and_swap(volatile char *, char, char,...);
     
    139163_Bool __sync_bool_compare_and_swap(volatile long long int *, long long int, long long int,...);
    140164_Bool __sync_bool_compare_and_swap_8(volatile long long int *, long long int, long long int,...);
     165#if defined(__SIZEOF_INT128__)
    141166_Bool __sync_bool_compare_and_swap(volatile __int128 *, __int128, __int128,...);
    142167_Bool __sync_bool_compare_and_swap_16(volatile __int128 *, __int128, __int128,...);
     168#endif
    143169
    144170char __sync_val_compare_and_swap(volatile char *, char, char,...);
     
    150176long long int __sync_val_compare_and_swap(volatile long long int *, long long int, long long int,...);
    151177long long int __sync_val_compare_and_swap_8(volatile long long int *, long long int, long long int,...);
     178#if defined(__SIZEOF_INT128__)
    152179__int128 __sync_val_compare_and_swap(volatile __int128 *, __int128, __int128,...);
    153180__int128 __sync_val_compare_and_swap_16(volatile __int128 *, __int128, __int128,...);
     181#endif
    154182
    155183char __sync_lock_test_and_set(volatile char *, char,...);
     
    161189long long int __sync_lock_test_and_set(volatile long long int *, long long int,...);
    162190long long int __sync_lock_test_and_set_8(volatile long long int *, long long int,...);
     191#if defined(__SIZEOF_INT128__)
    163192__int128 __sync_lock_test_and_set(volatile __int128 *, __int128,...);
    164193__int128 __sync_lock_test_and_set_16(volatile __int128 *, __int128,...);
     194#endif
    165195
    166196void __sync_lock_release(volatile char *,...);
     
    172202void __sync_lock_release(volatile long long int *,...);
    173203void __sync_lock_release_8(volatile long long int *,...);
     204#if defined(__SIZEOF_INT128__)
    174205void __sync_lock_release(volatile __int128 *,...);
    175206void __sync_lock_release_16(volatile __int128 *,...);
     207#endif
    176208
    177209void __sync_synchronize();
     
    185217_Bool __atomic_test_and_set(volatile int *, int);
    186218_Bool __atomic_test_and_set(volatile long long int *, int);
     219#if defined(__SIZEOF_INT128__)
    187220_Bool __atomic_test_and_set(volatile __int128 *, int);
     221#endif
     222
    188223void __atomic_clear(volatile _Bool *, int);
    189224void __atomic_clear(volatile char *, int);
     
    191226void __atomic_clear(volatile int *, int);
    192227void __atomic_clear(volatile long long int *, int);
     228#if defined(__SIZEOF_INT128__)
    193229void __atomic_clear(volatile __int128 *, int);
     230#endif
    194231
    195232char __atomic_exchange_n(volatile char *, volatile char *, int);
     
    205242long long int __atomic_exchange_8(volatile long long int *, long long int, int);
    206243void __atomic_exchange(volatile long long int *, volatile long long int *, volatile long long int *, int);
     244#if defined(__SIZEOF_INT128__)
    207245__int128 __atomic_exchange_n(volatile __int128 *, volatile __int128 *, int);
    208246__int128 __atomic_exchange_16(volatile __int128 *, __int128, int);
    209247void __atomic_exchange(volatile __int128 *, volatile __int128 *, volatile __int128 *, int);
    210 
     248#endif
     249
     250_Bool __atomic_load_n(const volatile _Bool *, int);
     251void __atomic_load(const volatile _Bool *, volatile _Bool *, int);
    211252char __atomic_load_n(const volatile char *, int);
    212253char __atomic_load_1(const volatile char *, int);
     
    221262long long int __atomic_load_8(const volatile long long int *, int);
    222263void __atomic_load(const volatile long long int *, volatile long long int *, int);
     264#if defined(__SIZEOF_INT128__)
    223265__int128 __atomic_load_n(const volatile __int128 *, int);
    224266__int128 __atomic_load_16(const volatile __int128 *, int);
    225267void __atomic_load(const volatile __int128 *, volatile __int128 *, int);
     268#endif
    226269
    227270_Bool __atomic_compare_exchange_n(volatile char *, char *, char, _Bool, int, int);
     
    237280_Bool __atomic_compare_exchange_8(volatile long long int *, long long int *, long long int, _Bool, int, int);
    238281_Bool __atomic_compare_exchange  (volatile long long int *, long long int *, long long int *, _Bool, int, int);
     282#if defined(__SIZEOF_INT128__)
    239283_Bool __atomic_compare_exchange_n (volatile __int128 *, __int128 *, __int128, _Bool, int, int);
    240284_Bool __atomic_compare_exchange_16(volatile __int128 *, __int128 *, __int128, _Bool, int, int);
    241285_Bool __atomic_compare_exchange   (volatile __int128 *, __int128 *, __int128 *, _Bool, int, int);
     286#endif
    242287
    243288void __atomic_store_n(volatile _Bool *, _Bool, int);
    244 void __atomic_store_1(volatile _Bool *, _Bool, int);
    245289void __atomic_store(volatile _Bool *, _Bool *, int);
    246290void __atomic_store_n(volatile char *, char, int);
     
    256300void __atomic_store_8(volatile long long int *, long long int, int);
    257301void __atomic_store(volatile long long int *, long long int *, int);
     302#if defined(__SIZEOF_INT128__)
    258303void __atomic_store_n(volatile __int128 *, __int128, int);
    259304void __atomic_store_16(volatile __int128 *, __int128, int);
    260305void __atomic_store(volatile __int128 *, __int128 *, int);
     306#endif
    261307
    262308char __atomic_add_fetch  (volatile char *, char, int);
     
    268314long long int __atomic_add_fetch  (volatile long long int *, long long int, int);
    269315long long int __atomic_add_fetch_8(volatile long long int *, long long int, int);
     316#if defined(__SIZEOF_INT128__)
    270317__int128 __atomic_add_fetch   (volatile __int128 *, __int128, int);
    271318__int128 __atomic_add_fetch_16(volatile __int128 *, __int128, int);
     319#endif
    272320
    273321char __atomic_sub_fetch  (volatile char *, char, int);
     
    279327long long int __atomic_sub_fetch  (volatile long long int *, long long int, int);
    280328long long int __atomic_sub_fetch_8(volatile long long int *, long long int, int);
     329#if defined(__SIZEOF_INT128__)
    281330__int128 __atomic_sub_fetch   (volatile __int128 *, __int128, int);
    282331__int128 __atomic_sub_fetch_16(volatile __int128 *, __int128, int);
     332#endif
    283333
    284334char __atomic_and_fetch  (volatile char *, char, int);
     
    290340long long int __atomic_and_fetch  (volatile long long int *, long long int, int);
    291341long long int __atomic_and_fetch_8(volatile long long int *, long long int, int);
     342#if defined(__SIZEOF_INT128__)
    292343__int128 __atomic_and_fetch   (volatile __int128 *, __int128, int);
    293344__int128 __atomic_and_fetch_16(volatile __int128 *, __int128, int);
     345#endif
    294346
    295347char __atomic_nand_fetch  (volatile char *, char, int);
     
    301353long long int __atomic_nand_fetch  (volatile long long int *, long long int, int);
    302354long long int __atomic_nand_fetch_8(volatile long long int *, long long int, int);
     355#if defined(__SIZEOF_INT128__)
    303356__int128 __atomic_nand_fetch   (volatile __int128 *, __int128, int);
    304357__int128 __atomic_nand_fetch_16(volatile __int128 *, __int128, int);
     358#endif
    305359
    306360char __atomic_xor_fetch  (volatile char *, char, int);
     
    312366long long int __atomic_xor_fetch  (volatile long long int *, long long int, int);
    313367long long int __atomic_xor_fetch_8(volatile long long int *, long long int, int);
     368#if defined(__SIZEOF_INT128__)
    314369__int128 __atomic_xor_fetch   (volatile __int128 *, __int128, int);
    315370__int128 __atomic_xor_fetch_16(volatile __int128 *, __int128, int);
     371#endif
    316372
    317373char __atomic_or_fetch  (volatile char *, char, int);
     
    323379long long int __atomic_or_fetch  (volatile long long int *, long long int, int);
    324380long long int __atomic_or_fetch_8(volatile long long int *, long long int, int);
     381#if defined(__SIZEOF_INT128__)
    325382__int128 __atomic_or_fetch   (volatile __int128 *, __int128, int);
    326383__int128 __atomic_or_fetch_16(volatile __int128 *, __int128, int);
     384#endif
    327385
    328386char __atomic_fetch_add  (volatile char *, char, int);
     
    334392long long int __atomic_fetch_add  (volatile long long int *, long long int, int);
    335393long long int __atomic_fetch_add_8(volatile long long int *, long long int, int);
     394#if defined(__SIZEOF_INT128__)
    336395__int128 __atomic_fetch_add   (volatile __int128 *, __int128, int);
    337396__int128 __atomic_fetch_add_16(volatile __int128 *, __int128, int);
     397#endif
    338398
    339399char __atomic_fetch_sub  (volatile char *, char, int);
     
    345405long long int __atomic_fetch_sub  (volatile long long int *, long long int, int);
    346406long long int __atomic_fetch_sub_8(volatile long long int *, long long int, int);
     407#if defined(__SIZEOF_INT128__)
    347408__int128 __atomic_fetch_sub   (volatile __int128 *, __int128, int);
    348409__int128 __atomic_fetch_sub_16(volatile __int128 *, __int128, int);
     410#endif
    349411
    350412char __atomic_fetch_and  (volatile char *, char, int);
     
    356418long long int __atomic_fetch_and  (volatile long long int *, long long int, int);
    357419long long int __atomic_fetch_and_8(volatile long long int *, long long int, int);
     420#if defined(__SIZEOF_INT128__)
    358421__int128 __atomic_fetch_and   (volatile __int128 *, __int128, int);
    359422__int128 __atomic_fetch_and_16(volatile __int128 *, __int128, int);
     423#endif
    360424
    361425char __atomic_fetch_nand  (volatile char *, char, int);
     
    367431long long int __atomic_fetch_nand  (volatile long long int *, long long int, int);
    368432long long int __atomic_fetch_nand_8(volatile long long int *, long long int, int);
     433#if defined(__SIZEOF_INT128__)
    369434__int128 __atomic_fetch_nand   (volatile __int128 *, __int128, int);
    370435__int128 __atomic_fetch_nand_16(volatile __int128 *, __int128, int);
     436#endif
    371437
    372438char __atomic_fetch_xor  (volatile char *, char, int);
     
    378444long long int __atomic_fetch_xor  (volatile long long int *, long long int, int);
    379445long long int __atomic_fetch_xor_8(volatile long long int *, long long int, int);
     446#if defined(__SIZEOF_INT128__)
    380447__int128 __atomic_fetch_xor   (volatile __int128 *, __int128, int);
    381448__int128 __atomic_fetch_xor_16(volatile __int128 *, __int128, int);
     449#endif
    382450
    383451char __atomic_fetch_or  (volatile char *, char, int);
     
    389457long long int __atomic_fetch_or  (volatile long long int *, long long int, int);
    390458long long int __atomic_fetch_or_8(volatile long long int *, long long int, int);
     459#if defined(__SIZEOF_INT128__)
    391460__int128 __atomic_fetch_or   (volatile __int128 *, __int128, int);
    392461__int128 __atomic_fetch_or_16(volatile __int128 *, __int128, int);
     462#endif
    393463
    394464_Bool __atomic_always_lock_free(unsigned long, const volatile void *);
  • src/tests/.gitignore

    r0182bfa r28f3a19  
    11.out/
    22.err/
     3.type
  • src/tests/Makefile.am

    r0182bfa r28f3a19  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Mon Nov 27 21:34:33 2017
    14 ## Update Count     : 48
     13## Last Modified On : Wed Jun  6 16:42:20 2018
     14## Update Count     : 49
    1515###############################################################################
    1616
     
    2828DEBUG_FLAGS =
    2929
    30 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@
     30BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -I.
    3131if !BUILD_DEBUG
    3232BUILD_FLAGS += -nodebug
     
    9292        ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@}
    9393
    94 literals : literals.c @CFA_BINDIR@/@CFA_NAME@
    95         ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@}
    96 
    9794sched-ext-parse : sched-ext-parse.c @CFA_BINDIR@/@CFA_NAME@
    9895        ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@}
  • src/tests/Makefile.in

    r0182bfa r28f3a19  
    309309# applies to both programs
    310310DEBUG_FLAGS =
    311 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ \
     311BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -I. \
    312312        $(am__append_1) $(am__append_2) $(am__append_3)
    313313TEST_FLAGS = $(if $(test), 2> $(test), )
     
    769769        ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@}
    770770
    771 literals : literals.c @CFA_BINDIR@/@CFA_NAME@
    772         ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@}
    773 
    774771sched-ext-parse : sched-ext-parse.c @CFA_BINDIR@/@CFA_NAME@
    775772        ${CC} ${AM_CFLAGS} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@}
  • src/tests/builtins/sync.c

    r0182bfa r28f3a19  
    88        volatile int * vp4 = 0; int * rp4 = 0; int v4 = 0;
    99        volatile long long int * vp8 = 0; long long int * rp8 = 0; long long int v8 = 0;
     10        #if defined(__SIZEOF_INT128__)
    1011        volatile __int128 * vp16 = 0; __int128 * rp16 = 0; __int128 v16 = 0;
     12        #endif
    1113
    1214        { char ret; ret = __sync_fetch_and_add(vp1, v1); }
     
    1820        { long long int ret; ret = __sync_fetch_and_add(vp8, v8); }
    1921        { long long int ret; ret = __sync_fetch_and_add_8(vp8, v8); }
     22        #if defined(__SIZEOF_INT128__)
    2023        { __int128 ret; ret = __sync_fetch_and_add(vp16, v16); }
    2124        { __int128 ret; ret = __sync_fetch_and_add_16(vp16, v16); }
     25        #endif
    2226
    2327        { char ret; ret = __sync_fetch_and_sub(vp1, v1); }
     
    2933        { long long int ret; ret = __sync_fetch_and_sub(vp8, v8); }
    3034        { long long int ret; ret = __sync_fetch_and_sub_8(vp8, v8); }
     35        #if defined(__SIZEOF_INT128__)
    3136        { __int128 ret; ret = __sync_fetch_and_sub(vp16, v16); }
    3237        { __int128 ret; ret = __sync_fetch_and_sub_16(vp16, v16); }
     38        #endif
    3339
    3440        { char ret; ret = __sync_fetch_and_or(vp1, v1); }
     
    4046        { long long int ret; ret = __sync_fetch_and_or(vp8, v8); }
    4147        { long long int ret; ret = __sync_fetch_and_or_8(vp8, v8); }
     48        #if defined(__SIZEOF_INT128__)
    4249        { __int128 ret; ret = __sync_fetch_and_or(vp16, v16); }
    4350        { __int128 ret; ret = __sync_fetch_and_or_16(vp16, v16); }
     51        #endif
    4452
    4553        { char ret; ret = __sync_fetch_and_and(vp1, v1); }
     
    5159        { long long int ret; ret = __sync_fetch_and_and(vp8, v8); }
    5260        { long long int ret; ret = __sync_fetch_and_and_8(vp8, v8); }
     61        #if defined(__SIZEOF_INT128__)
    5362        { __int128 ret; ret = __sync_fetch_and_and(vp16, v16); }
    5463        { __int128 ret; ret = __sync_fetch_and_and_16(vp16, v16); }
     64        #endif
    5565
    5666        { char ret; ret = __sync_fetch_and_xor(vp1, v1); }
     
    6272        { long long int ret; ret = __sync_fetch_and_xor(vp8, v8); }
    6373        { long long int ret; ret = __sync_fetch_and_xor_8(vp8, v8); }
     74        #if defined(__SIZEOF_INT128__)
    6475        { __int128 ret; ret = __sync_fetch_and_xor(vp16, v16); }
    6576        { __int128 ret; ret = __sync_fetch_and_xor_16(vp16, v16); }
     77        #endif
    6678
    6779        { char ret; ret = __sync_fetch_and_nand(vp1, v1); }
     
    7385        { long long int ret; ret = __sync_fetch_and_nand(vp8, v8); }
    7486        { long long int ret; ret = __sync_fetch_and_nand_8(vp8, v8); }
     87        #if defined(__SIZEOF_INT128__)
    7588        { __int128 ret; ret = __sync_fetch_and_nand(vp16, v16); }
    7689        { __int128 ret; ret = __sync_fetch_and_nand_16(vp16, v16); }
     90        #endif
    7791
    7892        { char ret; ret = __sync_add_and_fetch(vp1, v1); }
     
    8498        { long long int ret; ret = __sync_add_and_fetch(vp8, v8); }
    8599        { long long int ret; ret = __sync_add_and_fetch_8(vp8, v8); }
     100        #if defined(__SIZEOF_INT128__)
    86101        { __int128 ret; ret = __sync_add_and_fetch(vp16, v16); }
    87102        { __int128 ret; ret = __sync_add_and_fetch_16(vp16, v16); }
     103        #endif
    88104
    89105        { char ret; ret = __sync_sub_and_fetch(vp1, v1); }
     
    95111        { long long int ret; ret = __sync_sub_and_fetch(vp8, v8); }
    96112        { long long int ret; ret = __sync_sub_and_fetch_8(vp8, v8); }
     113        #if defined(__SIZEOF_INT128__)
    97114        { __int128 ret; ret = __sync_sub_and_fetch(vp16, v16); }
    98115        { __int128 ret; ret = __sync_sub_and_fetch_16(vp16, v16); }
     116        #endif
    99117
    100118        { char ret; ret = __sync_or_and_fetch(vp1, v1); }
     
    106124        { long long int ret; ret = __sync_or_and_fetch(vp8, v8); }
    107125        { long long int ret; ret = __sync_or_and_fetch_8(vp8, v8); }
     126        #if defined(__SIZEOF_INT128__)
    108127        { __int128 ret; ret = __sync_or_and_fetch(vp16, v16); }
    109128        { __int128 ret; ret = __sync_or_and_fetch_16(vp16, v16); }
     129        #endif
    110130
    111131        { char ret; ret = __sync_and_and_fetch(vp1, v1); }
     
    117137        { long long int ret; ret = __sync_and_and_fetch(vp8, v8); }
    118138        { long long int ret; ret = __sync_and_and_fetch_8(vp8, v8); }
     139        #if defined(__SIZEOF_INT128__)
    119140        { __int128 ret; ret = __sync_and_and_fetch(vp16, v16); }
    120141        { __int128 ret; ret = __sync_and_and_fetch_16(vp16, v16); }
     142        #endif
    121143
    122144        { char ret; ret = __sync_xor_and_fetch(vp1, v1); }
     
    128150        { long long int ret; ret = __sync_xor_and_fetch(vp8, v8); }
    129151        { long long int ret; ret = __sync_xor_and_fetch_8(vp8, v8); }
     152        #if defined(__SIZEOF_INT128__)
    130153        { __int128 ret; ret = __sync_xor_and_fetch(vp16, v16); }
    131154        { __int128 ret; ret = __sync_xor_and_fetch_16(vp16, v16); }
     155        #endif
    132156
    133157        { char ret; ret = __sync_nand_and_fetch(vp1, v1); }
     
    139163        { long long int ret; ret = __sync_nand_and_fetch(vp8, v8); }
    140164        { long long int ret; ret = __sync_nand_and_fetch_8(vp8, v8); }
     165        #if defined(__SIZEOF_INT128__)
    141166        { __int128 ret; ret = __sync_nand_and_fetch(vp16, v16); }
    142167        { __int128 ret; ret = __sync_nand_and_fetch_16(vp16, v16); }
     168        #endif
    143169
    144170        { _Bool ret; ret = __sync_bool_compare_and_swap(vp1, v1, v1); }
     
    150176        { _Bool ret; ret = __sync_bool_compare_and_swap(vp8, v8, v8); }
    151177        { _Bool ret; ret = __sync_bool_compare_and_swap_8(vp8, v8, v8); }
     178        #if defined(__SIZEOF_INT128__)
    152179        { _Bool ret; ret = __sync_bool_compare_and_swap(vp16, v16, v16); }
    153180        { _Bool ret; ret = __sync_bool_compare_and_swap_16(vp16, v16,v16); }
     181        #endif
    154182
    155183        { char ret; ret = __sync_val_compare_and_swap(vp1, v1, v1); }
     
    161189        { long long int ret; ret = __sync_val_compare_and_swap(vp8, v8, v8); }
    162190        { long long int ret; ret = __sync_val_compare_and_swap_8(vp8, v8, v8); }
     191        #if defined(__SIZEOF_INT128__)
    163192        { __int128 ret; ret = __sync_val_compare_and_swap(vp16, v16, v16); }
    164193        { __int128 ret; ret = __sync_val_compare_and_swap_16(vp16, v16,v16); }
     194        #endif
    165195
    166196        { char ret; ret = __sync_lock_test_and_set(vp1, v1); }
     
    172202        { long long int ret; ret = __sync_lock_test_and_set(vp8, v8); }
    173203        { long long int ret; ret = __sync_lock_test_and_set_8(vp8, v8); }
     204        #if defined(__SIZEOF_INT128__)
    174205        { __int128 ret; ret = __sync_lock_test_and_set(vp16, v16); }
    175206        { __int128 ret; ret = __sync_lock_test_and_set_16(vp16, v16); }
     207        #endif
    176208
    177209        { __sync_lock_release(vp1); }
     
    183215        { __sync_lock_release(vp8); }
    184216        { __sync_lock_release_8(vp8); }
     217        #if defined(__SIZEOF_INT128__)
    185218        { __sync_lock_release(vp16); }
    186219        { __sync_lock_release_16(vp16); }
     220        #endif
    187221
    188222        { __sync_synchronize(); }
     
    208242        { long long int ret; ret = __atomic_exchange_8(vp8, v8, __ATOMIC_SEQ_CST); }
    209243        { long long int ret; __atomic_exchange(vp8, &v8, &ret, __ATOMIC_SEQ_CST); }
     244        #if defined(__SIZEOF_INT128__)
    210245        { __int128 ret; ret = __atomic_exchange_n(vp16, &v16, __ATOMIC_SEQ_CST); }
    211246        { __int128 ret; ret = __atomic_exchange_16(vp16, v16, __ATOMIC_SEQ_CST); }
    212247        { __int128 ret; __atomic_exchange(vp16, &v16, &ret, __ATOMIC_SEQ_CST); }
     248        #endif
    213249
    214250        { char ret; ret = __atomic_load_n(vp1, __ATOMIC_SEQ_CST); }
     
    224260        { long long int ret; ret = __atomic_load_8(vp8, __ATOMIC_SEQ_CST); }
    225261        { long long int ret; __atomic_load(vp8, &ret, __ATOMIC_SEQ_CST); }
     262        #if defined(__SIZEOF_INT128__)
    226263        { __int128 ret; ret = __atomic_load_n(vp16, __ATOMIC_SEQ_CST); }
    227264        { __int128 ret; ret = __atomic_load_16(vp16, __ATOMIC_SEQ_CST); }
    228265        { __int128 ret; __atomic_load(vp16, &ret, __ATOMIC_SEQ_CST); }
     266        #endif
    229267
    230268        { _Bool ret; ret = __atomic_compare_exchange_n(vp1, rp1, v1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     
    240278        { _Bool ret; ret = __atomic_compare_exchange_8(vp8, rp8, v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    241279        { _Bool ret; ret = __atomic_compare_exchange(vp8, rp8, &v8, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     280        #if defined(__SIZEOF_INT128__)
    242281        { _Bool ret; ret = __atomic_compare_exchange_n(vp16, rp16, v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    243282        { _Bool ret; ret = __atomic_compare_exchange_16(vp16, rp16, v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
    244283        { _Bool ret; ret = __atomic_compare_exchange(vp16, rp16, &v16, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); }
     284        #endif
    245285
    246286        { __atomic_store_n(vp1, v1, __ATOMIC_SEQ_CST); }
     
    256296        { __atomic_store_8(vp8, v8, __ATOMIC_SEQ_CST); }
    257297        { __atomic_store(vp8, &v8, __ATOMIC_SEQ_CST); }
     298        #if defined(__SIZEOF_INT128__)
    258299        { __atomic_store_n(vp16, v16, __ATOMIC_SEQ_CST); }
    259300        { __atomic_store_16(vp16, v16, __ATOMIC_SEQ_CST); }
    260301        { __atomic_store(vp16, &v16, __ATOMIC_SEQ_CST); }
     302        #endif
    261303
    262304        { char ret; ret = __atomic_add_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
     
    268310        { long long int ret; ret = __atomic_add_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    269311        { long long int ret; ret = __atomic_add_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
     312        #if defined(__SIZEOF_INT128__)
    270313        { __int128 ret; ret = __atomic_add_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    271314        { __int128 ret; ret = __atomic_add_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
     315        #endif
    272316
    273317        { char ret; ret = __atomic_sub_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
     
    279323        { long long int ret; ret = __atomic_sub_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    280324        { long long int ret; ret = __atomic_sub_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
     325        #if defined(__SIZEOF_INT128__)
    281326        { __int128 ret; ret = __atomic_sub_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    282327        { __int128 ret; ret = __atomic_sub_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
     328        #endif
    283329
    284330        { char ret; ret = __atomic_and_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
     
    290336        { long long int ret; ret = __atomic_and_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    291337        { long long int ret; ret = __atomic_and_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
     338        #if defined(__SIZEOF_INT128__)
    292339        { __int128 ret; ret = __atomic_and_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    293340        { __int128 ret; ret = __atomic_and_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
     341        #endif
    294342
    295343        { char ret; ret = __atomic_nand_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
     
    301349        { long long int ret; ret = __atomic_nand_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    302350        { long long int ret; ret = __atomic_nand_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
     351        #if defined(__SIZEOF_INT128__)
    303352        { __int128 ret; ret = __atomic_nand_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    304353        { __int128 ret; ret = __atomic_nand_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
     354        #endif
    305355
    306356        { char ret; ret = __atomic_xor_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
     
    312362        { long long int ret; ret = __atomic_xor_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    313363        { long long int ret; ret = __atomic_xor_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
     364        #if defined(__SIZEOF_INT128__)
    314365        { __int128 ret; ret = __atomic_xor_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    315366        { __int128 ret; ret = __atomic_xor_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
     367        #endif
    316368
    317369        { char ret; ret = __atomic_or_fetch(vp1, v1, __ATOMIC_SEQ_CST); }
     
    323375        { long long int ret; ret = __atomic_or_fetch(vp8, v8, __ATOMIC_SEQ_CST); }
    324376        { long long int ret; ret = __atomic_or_fetch_8(vp8, v8, __ATOMIC_SEQ_CST); }
     377        #if defined(__SIZEOF_INT128__)
    325378        { __int128 ret; ret = __atomic_or_fetch(vp16, v16, __ATOMIC_SEQ_CST); }
    326379        { __int128 ret; ret = __atomic_or_fetch_16(vp16, v16, __ATOMIC_SEQ_CST); }
     380        #endif
    327381
    328382        { char ret; ret = __atomic_fetch_add(vp1, v1, __ATOMIC_SEQ_CST); }
     
    334388        { long long int ret; ret = __atomic_fetch_add(vp8, v8, __ATOMIC_SEQ_CST); }
    335389        { long long int ret; ret = __atomic_fetch_add_8(vp8, v8, __ATOMIC_SEQ_CST); }
     390        #if defined(__SIZEOF_INT128__)
    336391        { __int128 ret; ret = __atomic_fetch_add(vp16, v16, __ATOMIC_SEQ_CST); }
    337392        { __int128 ret; ret = __atomic_fetch_add_16(vp16, v16, __ATOMIC_SEQ_CST); }
     393        #endif
    338394
    339395        { char ret; ret = __atomic_fetch_sub(vp1, v1, __ATOMIC_SEQ_CST); }
     
    345401        { long long int ret; ret = __atomic_fetch_sub(vp8, v8, __ATOMIC_SEQ_CST); }
    346402        { long long int ret; ret = __atomic_fetch_sub_8(vp8, v8, __ATOMIC_SEQ_CST); }
     403        #if defined(__SIZEOF_INT128__)
    347404        { __int128 ret; ret = __atomic_fetch_sub(vp16, v16, __ATOMIC_SEQ_CST); }
    348405        { __int128 ret; ret = __atomic_fetch_sub_16(vp16, v16, __ATOMIC_SEQ_CST); }
     406        #endif
    349407
    350408        { char ret; ret = __atomic_fetch_and(vp1, v1, __ATOMIC_SEQ_CST); }
     
    356414        { long long int ret; ret = __atomic_fetch_and(vp8, v8, __ATOMIC_SEQ_CST); }
    357415        { long long int ret; ret = __atomic_fetch_and_8(vp8, v8, __ATOMIC_SEQ_CST); }
     416        #if defined(__SIZEOF_INT128__)
    358417        { __int128 ret; ret = __atomic_fetch_and(vp16, v16, __ATOMIC_SEQ_CST); }
    359418        { __int128 ret; ret = __atomic_fetch_and_16(vp16, v16, __ATOMIC_SEQ_CST); }
     419        #endif
    360420
    361421        { char ret; ret = __atomic_fetch_nand(vp1, v1, __ATOMIC_SEQ_CST); }
     
    367427        { long long int ret; ret = __atomic_fetch_nand(vp8, v8, __ATOMIC_SEQ_CST); }
    368428        { long long int ret; ret = __atomic_fetch_nand_8(vp8, v8, __ATOMIC_SEQ_CST); }
     429        #if defined(__SIZEOF_INT128__)
    369430        { __int128 ret; ret = __atomic_fetch_nand(vp16, v16, __ATOMIC_SEQ_CST); }
    370431        { __int128 ret; ret = __atomic_fetch_nand_16(vp16, v16, __ATOMIC_SEQ_CST); }
     432        #endif
    371433
    372434        { char ret; ret = __atomic_fetch_xor(vp1, v1, __ATOMIC_SEQ_CST); }
     
    378440        { long long int ret; ret = __atomic_fetch_xor(vp8, v8, __ATOMIC_SEQ_CST); }
    379441        { long long int ret; ret = __atomic_fetch_xor_8(vp8, v8, __ATOMIC_SEQ_CST); }
     442        #if defined(__SIZEOF_INT128__)
    380443        { __int128 ret; ret = __atomic_fetch_xor(vp16, v16, __ATOMIC_SEQ_CST); }
    381444        { __int128 ret; ret = __atomic_fetch_xor_16(vp16, v16, __ATOMIC_SEQ_CST); }
     445        #endif
    382446
    383447        { char ret; ret = __atomic_fetch_or(vp1, v1, __ATOMIC_SEQ_CST); }
     
    389453        { long long int ret; ret = __atomic_fetch_or(vp8, v8, __ATOMIC_SEQ_CST); }
    390454        { long long int ret; ret = __atomic_fetch_or_8(vp8, v8, __ATOMIC_SEQ_CST); }
     455        #if defined(__SIZEOF_INT128__)
    391456        { __int128 ret; ret = __atomic_fetch_or(vp16, v16, __ATOMIC_SEQ_CST); }
    392457        { __int128 ret; ret = __atomic_fetch_or_16(vp16, v16, __ATOMIC_SEQ_CST); }
     458        #endif
    393459
    394460        { _Bool ret; ret = __atomic_always_lock_free(sizeof(int), vp4); }
  • src/tests/concurrent/coroutineYield.c

    r0182bfa r28f3a19  
    44#include <thread>
    55#include <time>
     6
     7#define __kick_rate 150000ul
     8#include "long_tests.h"
    69
    710#ifndef PREEMPTION_RATE
     
    1316}
    1417
    15 #ifdef LONG_TEST
     18#ifdef TEST_LONG
    1619static const unsigned long N = 600_000ul;
    1720#else
     
    2326void main(Coroutine& this) {
    2427        while(true) {
    25                 sout | "Coroutine 1" | endl;
     28                #if !defined(TEST_FOREVER)
     29                        sout | "Coroutine 1" | endl;
     30                #endif
    2631                yield();
    27                 sout | "Coroutine 2" | endl;
     32                #if !defined(TEST_FOREVER)
     33                        sout | "Coroutine 2" | endl;
     34                #endif
    2835                suspend();
    2936        }
     
    3340int main(int argc, char* argv[]) {
    3441        Coroutine c;
    35         for(int i = 0; i < N; i++) {
    36                 sout | "Thread 1" | endl;
     42        for(int i = 0; TEST(i < N); i++) {
     43                #if !defined(TEST_FOREVER)
     44                        sout | "Thread 1" | endl;
     45                #endif
    3746                resume(c);
    38                 sout | "Thread 2" | endl;
     47                #if !defined(TEST_FOREVER)
     48                        sout | "Thread 2" | endl;
     49                #endif
    3950                yield();
     51                KICK_WATCHDOG;
    4052        }
    4153}
  • src/tests/concurrent/examples/datingService.c

    r0182bfa r28f3a19  
    88// Created On       : Mon Oct 30 12:56:20 2017
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Wed Mar 14 22:48:40 2018
    11 // Update Count     : 23
     10// Last Modified On : Sun May 27 09:05:18 2018
     11// Update Count     : 26
    1212//
    1313
     
    1818#include <unistd.h>                                                                             // getpid
    1919
    20 enum { NoOfPairs = 20 };
     20enum { CompCodes = 20 };                                                                // number of compatibility codes
    2121
    2222monitor DatingService {
    23         condition Girls[NoOfPairs], Boys[NoOfPairs];
     23        condition Girls[CompCodes], Boys[CompCodes];
    2424        unsigned int GirlPhoneNo, BoyPhoneNo;
    2525}; // DatingService
     
    4747} // DatingService boy
    4848
    49 unsigned int girlck[NoOfPairs];
    50 unsigned int boyck[NoOfPairs];
     49unsigned int girlck[CompCodes];
     50unsigned int boyck[CompCodes];
    5151
    5252thread Girl {
     
    8888int main() {
    8989        DatingService TheExchange;
    90         Girl * girls[NoOfPairs];
    91         Boy  * boys[NoOfPairs];
     90        Girl * girls[CompCodes];
     91        Boy  * boys[CompCodes];
    9292
    9393        srandom( /*getpid()*/ 103 );
    9494
    95         for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
     95        for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
    9696                girls[i] = new( &TheExchange, i, i );
    97                 boys[i]  = new( &TheExchange, i, NoOfPairs - ( i + 1 ) );
     97                boys[i]  = new( &TheExchange, i, CompCodes - ( i + 1 ) );
    9898        } // for
    9999
    100         for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
     100        for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
    101101                delete( boys[i] );
    102102                delete( girls[i] );
    103103        } // for
    104104
    105         for ( unsigned int i = 0; i < NoOfPairs; i += 1 ) {
     105        for ( unsigned int i = 0; i < CompCodes; i += 1 ) {
    106106                if ( girlck[ boyck[i] ] != boyck[ girlck[i] ] ) abort();
    107107        } // for
  • src/tests/concurrent/preempt.c

    r0182bfa r28f3a19  
    22#include <thread>
    33#include <time>
     4
     5#include "long_tests.h"
    46
    57#ifndef PREEMPTION_RATE
     
    1113}
    1214
    13 #ifdef LONG_TEST
     15#ifdef TEST_LONG
    1416static const unsigned long N = 30_000ul;
    1517#else
     
    3032
    3133void main(worker_t & this) {
    32         while(counter < N) {
     34        while(TEST(counter < N)) {
    3335                __cfaabi_check_preemption();
    3436                if( (counter % 7) == this.value ) {
     
    4042                }
    4143                __cfaabi_check_preemption();
     44                KICK_WATCHDOG;
    4245        }
    4346}
  • src/tests/concurrent/signal/block.c

    r0182bfa r28f3a19  
    1414#include <time>
    1515
     16#include "long_tests.h"
     17
    1618#ifndef PREEMPTION_RATE
    1719#define PREEMPTION_RATE 10`ms
     
    2224}
    2325
    24 #ifdef LONG_TEST
     26#ifdef TEST_LONG
    2527static const unsigned long N = 150_000ul;
    2628#else
     
    4042}
    4143
    42 void ^?{} ( global_data_t & this ) {}
     44void ^?{} ( global_data_t & mutex this ) {}
    4345
    4446global_data_t globalA, globalB;
     
    6668thread Waiter {};
    6769void main( Waiter & this ) {
    68         for( int i = 0; i < N; i++ ) {
     70        for( int i = 0; TEST(i < N); i++ ) {
    6971                wait_op( globalA, globalB, i );
     72                KICK_WATCHDOG;
    7073        }
    7174}
  • src/tests/concurrent/signal/disjoint.c

    r0182bfa r28f3a19  
    44#include <thread>
    55#include <time>
     6
     7#include "long_tests.h"
    68
    79#ifndef PREEMPTION_RATE
     
    1315}
    1416
    15 #ifdef LONG_TEST
     17#ifdef TEST_LONG
    1618static const unsigned long N = 300_000ul;
    1719#else
     
    2628monitor global_data_t;
    2729void ?{}( global_data_t & this );
    28 void ^?{} ( global_data_t & this );
     30void ^?{} ( global_data_t & mutex this );
    2931
    3032monitor global_data_t {
     
    4244}
    4345
    44 void ^?{} ( global_data_t & this ) {}
     46void ^?{} ( global_data_t & mutex this ) {}
    4547
    4648//------------------------------------------------------------------------------
     
    6769        }
    6870
    69         d.counter++;
     71        #if !defined(TEST_FOREVER)
     72                d.counter++;
     73                if( (d.counter % 1000) == 0 ) sout | d.counter | endl;
     74        #endif
    7075
    71         if( (d.counter % 1000) == 0 ) sout | d.counter | endl;
    72 
    73         return d.counter < N;
     76        return TEST(d.counter < N);
    7477}
    7578
     
    7780
    7881void main( Waiter & this ) {
    79         while( wait( mut, data ) ) { yield(); }
     82        while( wait( mut, data ) ) { KICK_WATCHDOG; yield(); }
    8083}
    8184
     
    9497
    9598        //This is technically a mutual exclusion violation but the mutex monitor protects us
    96         bool running = data.counter < N && data.counter > 0;
     99        bool running = TEST(data.counter < N) && data.counter > 0;
    97100        if( data.state != SIGNAL && running ) {
    98101                sout | "ERROR Eager signal" | data.state | endl;
  • src/tests/concurrent/signal/wait.c

    r0182bfa r28f3a19  
    1212#include <time>
    1313
     14#define __kick_rate 12000ul
     15#include "long_tests.h"
     16
    1417#ifndef PREEMPTION_RATE
    1518#define PREEMPTION_RATE 10`ms
     
    2023}
    2124
    22 #ifdef LONG_TEST
     25#ifdef TEST_LONG
    2326static const unsigned long N = 375_000ul;
    2427#else
     
    9093// Waiter ABC
    9194void main( WaiterABC & this ) {
    92         for( int i = 0; i < N; i++ ) {
     95        for( int i = 0; TEST(i < N); i++ ) {
    9396                wait( condABC, globalA, globalB, globalC );
     97                KICK_WATCHDOG;
    9498        }
    9599
     
    100104// Waiter AB
    101105void main( WaiterAB & this ) {
    102         for( int i = 0; i < N; i++ ) {
     106        for( int i = 0; TEST(i < N); i++ ) {
    103107                wait( condAB , globalA, globalB );
     108                KICK_WATCHDOG;
    104109        }
    105110
     
    110115// Waiter AC
    111116void main( WaiterAC & this ) {
    112         for( int i = 0; i < N; i++ ) {
     117        for( int i = 0; TEST(i < N); i++ ) {
    113118                wait( condAC , globalA, globalC );
     119                KICK_WATCHDOG;
    114120        }
    115121
     
    120126// Waiter BC
    121127void main( WaiterBC & this ) {
    122         for( int i = 0; i < N; i++ ) {
     128        for( int i = 0; TEST(i < N); i++ ) {
    123129                wait( condBC , globalB, globalC );
     130                KICK_WATCHDOG;
    124131        }
    125132
  • src/tests/ifwhileCtl.c

    r0182bfa r28f3a19  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // ifcond.c --
     7// ifwhileCtl.c --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Aug 26 10:13:11 2017
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Sep 01 15:22:19 2017
    13 // Update Count     : 14
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jun  6 17:15:09 2018
     13// Update Count     : 21
    1414//
    1515
     
    4040                sout | "x != y incorrect" | endl;
    4141        } // if
     42
     43        if ( struct S { int i; } s = { 3 }; s.i < 4 ) {
     44                S s1;
     45                sout | "s.i < 4 correct" | endl;
     46        } else {
     47                S s1;
     48                sout | "s.i >= 4 incorrect" | endl;
     49        } // if
     50
     51        while ( int x = 1 ) {
     52                sout | "x != 0 correct" | endl;
     53                break;
     54        } // while
     55
     56        while ( int x = 4, y = 0 ) {
     57                sout | "x != 0 && y != 0 incorrect" | endl;
     58        } // while
     59
     60        while ( int x = 5, y = f( x ); x == y ) {
     61                sout | "x == y correct" | endl;
     62                break;
     63        } // while
     64
     65        while ( struct S { int i; } s = { 3 }; s.i < 4 ) {
     66                S s1;
     67                sout | "s.i < 4 correct" | endl;
     68                break;
     69        } // while
    4270} // main
    4371
    4472// Local Variables: //
    4573// tab-width: 4 //
    46 // compile-command: "cfa ifcond.c" //
     74// compile-command: "cfa ifwhileCtl.c" //
    4775// End: //
  • src/tests/preempt_longrun/Makefile.am

    r0182bfa r28f3a19  
    1919preempt=10ul\`ms
    2020debug=-debug
     21type=LONG
    2122
    2223REPEAT = ${abs_top_srcdir}/tools/repeat
     24WATCHDOG = ${abs_top_srcdir}/tools/watchdog
    2325TIME = /usr/bin/time -f "%E"
    2426
    25 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -DLONG_TEST
     27# $(shell ./update-type $(type))
     28# ./update-type $(type)
     29
     30UPDATED_TYPE = $(shell ./update-type $(type))
     31
     32BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell cat .type | tr a-z A-Z)
    2633CFLAGS = ${BUILD_FLAGS}
    2734CC = @CFA_BINDIR@/@CFA_NAME@
     
    2936TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
    3037
    31 .INTERMEDIATE: ${TESTS}
     38# .INTERMEDIATE: ${TESTS}
    3239
    3340all-local: ${TESTS:=.run}
    3441
     42runall : ${TESTS:=.run}
     43        @ echo "All programs terminated normally"
     44
     45watchall : ${TESTS:=.watch}
     46        @ echo "All programs terminated normally"
     47
     48compileall : ${TESTS}
     49        @ echo "Compiled"
     50
    3551clean-local:
    36         rm -f ${TESTS}
     52        rm -f ${TESTS} core* out.log .type
    3753
    38 % : %.c ${CC}
     54% : %.c ${CC} ${UPDATED_TYPE}
    3955        ${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug) -o ${@}
    4056
    4157%.run : % ${REPEAT}
    4258        @ time ${REPEAT} -r out.log -i -s $(repeats) timeout ${max_time} ./${<}
     59        @ rm ${<}
     60        @ echo -e "${<}: SUCCESS\n"
     61
     62%.watch : % ${WATCHDOG}
     63        @ time ${WATCHDOG} ./${<}
    4364        @ rm ${<}
    4465        @ echo -e "${<}: SUCCESS\n"
     
    4970        @ echo -e "${<}: SUCCESS\n"
    5071
    51 ${REPEAT}:
     72${REPEAT}: ${abs_top_srcdir}/tools/Makefile
    5273        @+make -C ${abs_top_srcdir}/tools/
     74
     75${WATCHDOG}: ${abs_top_srcdir}/tools/Makefile
     76        @+make -C ${abs_top_srcdir}/tools/
  • src/tests/preempt_longrun/Makefile.in

    r0182bfa r28f3a19  
    452452preempt = 10ul\`ms
    453453debug = -debug
     454type = LONG
    454455REPEAT = ${abs_top_srcdir}/tools/repeat
     456WATCHDOG = ${abs_top_srcdir}/tools/watchdog
    455457TIME = /usr/bin/time -f "%E"
    456 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -DLONG_TEST
     458
     459# $(shell ./update-type $(type))
     460# ./update-type $(type)
     461UPDATED_TYPE = $(shell ./update-type $(type))
     462BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -O2 -DPREEMPTION_RATE=${preempt} -I.. -I. -DTEST_$(shell cat .type | tr a-z A-Z)
    457463TESTS = block coroutine create disjoint enter enter3 processor stack wait yield
    458464all: all-am
     
    873879
    874880
    875 .INTERMEDIATE: ${TESTS}
     881# .INTERMEDIATE: ${TESTS}
    876882
    877883all-local: ${TESTS:=.run}
    878884
     885runall : ${TESTS:=.run}
     886        @ echo "All programs terminated normally"
     887
     888watchall : ${TESTS:=.watch}
     889        @ echo "All programs terminated normally"
     890
     891compileall : ${TESTS}
     892        @ echo "Compiled"
     893
    879894clean-local:
    880         rm -f ${TESTS}
    881 
    882 % : %.c ${CC}
     895        rm -f ${TESTS} core* out.log .type
     896
     897% : %.c ${CC} ${UPDATED_TYPE}
    883898        ${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug) -o ${@}
    884899
     
    888903        @ echo -e "${<}: SUCCESS\n"
    889904
     905%.watch : % ${WATCHDOG}
     906        @ time ${WATCHDOG} ./${<}
     907        @ rm ${<}
     908        @ echo -e "${<}: SUCCESS\n"
     909
    890910%.time : % ${REPEAT}
    891911        @ ${REPEAT} -i -s -- $(repeats) $(TIME) -a -o times.log ./${<}
     
    893913        @ echo -e "${<}: SUCCESS\n"
    894914
    895 ${REPEAT}:
     915${REPEAT}: ${abs_top_srcdir}/tools/Makefile
     916        @+make -C ${abs_top_srcdir}/tools/
     917
     918${WATCHDOG}: ${abs_top_srcdir}/tools/Makefile
    896919        @+make -C ${abs_top_srcdir}/tools/
    897920
  • src/tests/preempt_longrun/create.c

    r0182bfa r28f3a19  
    22#include <thread>
    33#include <time>
     4
     5#include "long_tests.h"
    46
    57#ifndef PREEMPTION_RATE
     
    1921int main(int argc, char* argv[]) {
    2022        processor p;
    21         for(int i = 0; i < N; i++) {
     23        for(int i = 0; TEST(i < N); i++) {
    2224                worker_t w[7];
     25                KICK_WATCHDOG;
    2326        }
    2427}
  • src/tests/preempt_longrun/enter.c

    r0182bfa r28f3a19  
    33#include <thread>
    44#include <time>
     5
     6#define __kick_rate 75000ul
     7#include "long_tests.h"
    58
    69#ifndef PREEMPTION_RATE
     
    1518
    1619monitor mon_t {};
     20void foo( mon_t & mutex this ) {
     21        KICK_WATCHDOG;
     22}
    1723
    1824mon_t mon;
    19 
    20 void foo( mon_t & mutex this ) {}
    21 
    2225thread worker_t {};
    23 
    2426void main( worker_t & this ) {
    25         for( unsigned long i = 0; i < N; i++ ) {
     27        for( unsigned long i = 0; TEST(i < N); i++ ) {
    2628                foo( mon );
    2729        }
    28 }
    29 
    30 extern "C" {
    31 static worker_t * workers;
    3230}
    3331
     
    3634        {
    3735                worker_t w[7];
    38                 workers = w;
    3936        }
    4037}
  • src/tests/preempt_longrun/enter3.c

    r0182bfa r28f3a19  
    33#include <thread>
    44#include <time>
     5
     6#define __kick_rate 75000ul
     7#include "long_tests.h"
    58
    69#ifndef PREEMPTION_RATE
     
    1821mon_t mon1, mon2, mon3;
    1922
    20 void foo( mon_t & mutex a, mon_t & mutex b, mon_t & mutex c ) {}
     23void foo( mon_t & mutex a, mon_t & mutex b, mon_t & mutex c ) {
     24        KICK_WATCHDOG;
     25}
    2126
    2227thread worker_t {};
    2328
    2429void main( worker_t & this ) {
    25         for( unsigned long i = 0; i < N; i++ ) {
     30        for( unsigned long i = 0; TEST(i < N); i++ ) {
    2631                foo( mon1, mon2, mon3 );
    2732        }
  • src/tests/preempt_longrun/processor.c

    r0182bfa r28f3a19  
    22#include <thread>
    33#include <time>
     4
     5#include <unistd.h>
     6
     7#include "long_tests.h"
    48
    59#ifndef PREEMPTION_RATE
     
    1115}
    1216
    13 static const unsigned long N = 5_000ul;
     17static const unsigned long N = 50_000ul;
    1418
    1519int main(int argc, char* argv[]) {
     
    1822                p[pi] = new();
    1923        }
    20         for ( int i = 0; i < N; i++) {
     24        for ( int i = 0; TEST(i < N); i++) {
    2125                int pi = i % 15;
    2226                delete( p[pi] );
    2327                p[pi] = new();
     28                KICK_WATCHDOG;
     29        }
     30        for ( int pi = 0; pi < 15; pi++ ) {
     31                delete( p[pi] );
    2432        }
    2533}
  • src/tests/preempt_longrun/stack.c

    r0182bfa r28f3a19  
    33#include <thread>
    44#include <time>
     5
     6#define __kick_rate 5000000ul
     7#include "long_tests.h"
    58
    69#ifndef PREEMPTION_RATE
     
    1518
    1619void main(worker_t & this) {
    17         volatile long long p = 5_021_609ul;
    18         volatile long long a = 326_417ul;
    19         volatile long long n = 1l;
    20         for (volatile long long i = 0; i < p; i++) {
    21                 n *= a;
    22                 n %= p;
    23         }
     20        while(TEST(0)) {
     21                volatile long long p = 5_021_609ul;
     22                volatile long long a = 326_417ul;
     23                volatile long long n = 1l;
     24                for (volatile long long i = 0; i < p; i++) {
     25                        n *= a;
     26                        n %= p;
     27                        KICK_WATCHDOG;
     28                }
    2429
    25         if( n != a ) {
    26                 abort();
     30                if( !TEST(n == a) ) {
     31                        abort();
     32                }
    2733        }
    2834}
  • src/tests/preempt_longrun/yield.c

    r0182bfa r28f3a19  
    22#include <thread>
    33#include <time>
     4
     5#define __kick_rate 550000ul
     6#include "long_tests.h"
    47
    58#ifndef PREEMPTION_RATE
     
    1114}
    1215
    13 #ifdef LONG_TEST
     16#ifdef TEST_LONG
    1417static const unsigned long N = 9_750_000ul;
    1518#else
     
    2023
    2124void main(worker_t & this) {
    22         for(int i = 0; i < N; i++) {
     25        for(int i = 0; TEST(i < N); i++) {
    2326                yield();
     27                KICK_WATCHDOG;
    2428        }
    2529}
  • src/tests/pybin/tools.py

    r0182bfa r28f3a19  
    8383        return sh(cmd)
    8484
     85def which(program):
     86    import os
     87    def is_exe(fpath):
     88        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
     89
     90    fpath, fname = os.path.split(program)
     91    if fpath:
     92        if is_exe(program):
     93            return program
     94    else:
     95        for path in os.environ["PATH"].split(os.pathsep):
     96            exe_file = os.path.join(path, program)
     97            if is_exe(exe_file):
     98                return exe_file
     99
     100    return None
    85101################################################################################
    86102#               file handling
     
    219235        return False
    220236
     237def fancy_print(text):
     238        column = which('column')
     239        if column:
     240                cmd = "%s 2> /dev/null" % column
     241                print(cmd)
     242                proc = Popen(cmd, stdin=PIPE, stderr=None, shell=True)
     243                proc.communicate(input=text)
     244        else:
     245                print(text)
    221246
    222247settings.set_machine_default( getMachineType )
  • src/tests/raii/.expect/ctor-autogen-ERR1.txt

    r0182bfa r28f3a19  
    1 raii/ctor-autogen.c:102:1 error: No reasonable alternatives for expression Applying untyped:
    2   Name: ?{}
    3 ...to:
    4   Cast of:
    5     Variable Expression: x: instance of struct Managed with body 1
    6   ... to:
    7     reference to instance of struct Managed with body 1
    8   constant expression (123 123: signed int)
     1raii/ctor-autogen.c:102:1 error: Unique best alternative includes deleted identifier in Cast of:
     2  Application of
     3    Deleted Expression
     4      Variable Expression: ?{}: static inline function
     5      ... with parameters
     6        _dst: reference to instance of struct Managed with body 1
     7        x: signed int
     8      ... returning nothing
    99
     10      ... deleted by: ?{}: function
     11      ... with parameters
     12        m: reference to instance of struct Managed with body 1
     13      ... returning nothing
     14      ... with body
     15        CompoundStmt
     16          Expression Statement:
     17            Application of
     18              Variable Expression: ?=?: function
     19              ... with parameters
     20                intrinsic reference to signed int
     21                intrinsic signed int
     22              ... returning
     23                _retval__operator_assign: signed int
     24                ... with attributes:
     25                  Attribute with name: unused
     26
     27
     28            ... to arguments
     29              Cast of:
     30                Member Expression, with field:
     31                  x: signed int
     32                ... from aggregate:
     33                  Cast of:
     34                    Variable Expression: m: reference to instance of struct Managed with body 1
     35                  ... to:
     36                    instance of struct Managed with body 1
     37              ... to:
     38                reference to signed int
     39              Cast of:
     40                constant expression (0 0: zero_t)
     41              ... to:
     42                signed int
     43
     44            ... with environment:
     45              Types:
     46              Non-types:
     47
     48
     49  ... to arguments
     50    Cast of:
     51      Variable Expression: x: instance of struct Managed with body 1
     52    ... to:
     53      reference to instance of struct Managed with body 1
     54    constant expression (123 123: signed int)
     55
     56... to: nothing
  • src/tests/sum.c

    r0182bfa r28f3a19  
    1111// Created On       : Wed May 27 17:56:53 2015
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sat Feb 17 11:49:17 2018
    14 // Update Count     : 273
     13// Last Modified On : Sun Jun  3 19:23:41 2018
     14// Update Count     : 278
    1515//
    1616
     
    1818#include <stdlib>
    1919
    20 void ?{}( int & c, zero_t ) { c = 0; }
     20void ?{}( int & c, zero_t ) { c = 0; }                                  // not in prelude
    2121
    2222trait sumable( otype T ) {
    23         void ?{}( T &, zero_t );                                                        // constructor from 0 literal
     23        void ?{}( T &, zero_t );                                                        // 0 literal constructor
    2424        T ?+?( T, T );                                                                          // assortment of additions
    2525        T ?+=?( T &, T );
     
    2929
    3030forall( otype T | sumable( T ) )                                                // use trait
    31 T sum( unsigned int size, T a[] ) {
    32         T total = 0;                                                                            // instantiate T from 0 by calling constructor
    33         for ( unsigned int i = 0; i < size; i += 1 )
     31T sum( size_t size, T a[] ) {
     32        T total = 0;                                                                            // initialize by 0 constructor
     33        for ( size_t i = 0; i < size; i += 1 )
    3434                total += a[i];                                                                  // select appropriate +
    3535        return total;
     
    111111        for ( int i = 0; i < size; i += 1, v += 1 ) {
    112112                s += (int)v;
    113                 gs.x[i] = (int)v;                                                               // set filed array in generic type
     113                gs.x[i] = (int)v;                                                               // set field array in generic type
    114114        } // for
    115115        sout | "sum from" | low | "to" | High | "is"
    116                  | sum( size, gs.x ) | ", check" | (int)s | endl; // add filed array in generic type
     116                 | sum( size, gs.x ) | ", check" | (int)s | endl; // add field array in generic type
    117117} // main
    118118
  • src/tests/test.py

    r0182bfa r28f3a19  
    277277        elif options.list :
    278278                print("Listing for %s:%s"% (settings.arch.string, settings.debug.string))
    279                 print("\n".join(map(lambda t: "%s" % (t.toString()), tests)))
     279                fancy_print("\n".join(map(lambda t: "%s" % (t.toString()), tests)))
    280280
    281281        else :
Note: See TracChangeset for help on using the changeset viewer.