Changeset 235b41f


Ignore:
Timestamp:
Sep 5, 2017, 3:41:04 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
416cc86
Parents:
800d275 (diff), 3f8dd01 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
4 added
52 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/lstlang.sty

    r800d275 r235b41f  
    88%% Created On       : Sat May 13 16:34:42 2017
    99%% Last Modified By : Peter A. Buhr
    10 %% Last Modified On : Mon Jul 24 20:40:37 2017
    11 %% Update Count     : 13
     10%% Last Modified On : Wed Aug 30 22:11:14 2017
     11%% Update Count     : 14
    1212%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1313
     
    112112                finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t,
    113113                otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof,
    114                 __typeof__, virtual, with, zero_t},
     114                __typeof__, virtual, waitfor, when, with, zero_t},
    115115        morekeywords=[2]{
    116116                _Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex,
  • doc/refrat/keywords.tex

    r800d275 r235b41f  
    1111%% Created On       : Sun Aug  6 08:17:27 2017
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun Aug  6 08:31:42 2017
    14 %% Update Count     : 4
     13%% Last Modified On : Wed Aug 30 22:10:10 2017
     14%% Update Count     : 5
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616\begin{tabular}{@{}llllll@{}}
     
    5252©ttype©                 \\
    5353©virtual©               \\
    54 ©with©                  \\
     54©waitfor©               \\
    5555\end{tabular}
    5656&
    5757\begin{tabular}{@{}l@{}}
     58©when©                  \\
     59©with©                  \\
    5860©zero_t©                \\
    59                                 \\
    60                                 \\
    6161                                \\
    6262                                \\
  • src/CodeGen/CodeGenerator.cc

    r800d275 r235b41f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 18 15:34:00 2017
    13 // Update Count     : 488
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Sep  3 20:42:52 2017
     13// Update Count     : 490
    1414//
    1515#include "CodeGenerator.h"
     
    5959
    6060        void CodeGenerator::asmName( DeclarationWithType * decl ) {
    61                 if ( ConstantExpr * asmName = decl->get_asmName() ) {
     61                if ( ConstantExpr * asmName = dynamic_cast<ConstantExpr *>(decl->get_asmName()) ) {
    6262                        output << " asm ( " << asmName->get_constant()->get_value() << " )";
    6363                } // if
     
    195195                }
    196196
    197                 output << kind;
    198                 if ( aggDecl->get_name() != "" )
    199                         output << aggDecl->get_name();
     197                output << kind << aggDecl->get_name();
    200198
    201199                if ( aggDecl->has_body() ) {
     
    233231                genAttributes( enumDecl->get_attributes() );
    234232
    235                 if ( enumDecl->get_name() != "" )
    236                         output << enumDecl->get_name();
     233                output << enumDecl->get_name();
    237234
    238235                std::list< Declaration* > &memb = enumDecl->get_members();
     
    260257        }
    261258
    262         void CodeGenerator::visit( __attribute__((unused)) TraitDecl * traitDecl ) {}
     259        void CodeGenerator::visit( TraitDecl * traitDecl ) {
     260                assertf( ! genC, "TraitDecl nodes should not reach code generation." );
     261                extension( traitDecl );
     262                handleAggregate( traitDecl, "trait " );
     263        }
    263264
    264265        void CodeGenerator::visit( TypedefDecl * typeDecl ) {
     
    545546                extension( addressExpr );
    546547                output << "(&";
    547                 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
    548                 if ( VariableExpr * variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
    549                         output << mangleName( variableExpr->get_var() );
    550                 } else {
    551                         addressExpr->get_arg()->accept( *this );
    552                 } // if
     548                addressExpr->arg->accept( *this );
    553549                output << ")";
     550        }
     551
     552        void CodeGenerator::visit( LabelAddressExpr *addressExpr ) {
     553                extension( addressExpr );
     554                output << "(&&" << addressExpr->arg << ")";
    554555        }
    555556
     
    760761                for ( Statement * stmt : stmts ) {
    761762                        updateLocation( stmt );
    762                         output << printLabels( stmt->get_labels() );
     763                        output << indent << printLabels( stmt->get_labels() );
    763764                        if ( i+1 == numStmts ) {
    764765                                // last statement in a statement expression needs to be handled specially -
  • src/CodeGen/CodeGenerator.h

    r800d275 r235b41f  
    5959                virtual void visit( NameExpr *nameExpr );
    6060                virtual void visit( AddressExpr *addressExpr );
     61                virtual void visit( LabelAddressExpr *addressExpr );
    6162                virtual void visit( CastExpr *castExpr );
    6263                virtual void visit( VirtualCastExpr *castExpr );
  • src/CodeGen/Generate.cc

    r800d275 r235b41f  
    2121#include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
    2222#include "GenType.h"                 // for genPrettyType
     23#include "Common/PassVisitor.h"      // for PassVisitor
    2324#include "Parser/LinkageSpec.h"      // for isBuiltin, isGeneratable
    2425#include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
     
    2930
    3031namespace CodeGen {
     32        namespace {
     33                /// Removes misc. nodes that should not exist in CodeGen
     34                struct TreeCleaner {
     35                        void visit( CompoundStmt * stmt );
     36
     37                        static bool shouldClean( Declaration * );
     38                };
     39
     40                void cleanTree( std::list< Declaration * > & translationUnit ) {
     41                        PassVisitor<TreeCleaner> cleaner;
     42                        filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
     43                        acceptAll( translationUnit, cleaner );
     44                } // cleanTree
     45        } // namespace
     46
    3147        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks ) {
     48                cleanTree( translationUnit );
     49
    3250                CodeGen::CodeGenerator cgv( os, pretty, generateC, lineMarks );
    3351                for ( auto & dcl : translationUnit ) {
     
    5270                os << std::endl;
    5371        }
     72
     73        namespace {
     74                void TreeCleaner::visit( CompoundStmt * cstmt ) {
     75                        filter( cstmt->kids, [](Statement * stmt) {
     76                                if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     77                                        return shouldClean( declStmt->decl );
     78                                }
     79                                return false;
     80                        }, false );
     81                }
     82
     83                bool TreeCleaner::shouldClean( Declaration * decl ) {
     84                        return dynamic_cast< TraitDecl * >( decl );
     85                }
     86        } // namespace
    5487} // namespace CodeGen
    5588
  • src/CodeGen/OperatorTable.cc

    r800d275 r235b41f  
    1919
    2020#include "OperatorTable.h"
     21#include "Common/utility.h"
    2122
    2223namespace CodeGen {
     
    6566                        {       "?^=?",         "^=",   "_operator_bitxorassign",               OT_INFIXASSIGN          },
    6667                        {       "?|=?",         "|=",   "_operator_bitorassign",                OT_INFIXASSIGN          },
    67                         {       "&&",           "&&",   "&&",                                                   OT_LABELADDRESS         },
    68                         {       "0",            "0",    "_constant_zero",                               OT_CONSTANT                     },
    69                         {       "1",            "1",    "_constant_one",                                OT_CONSTANT                     }
    7068                };
    7169
     
    8684                        initialize();
    8785                } // if
     86
    8887                std::map< std::string, OperatorInfo >::const_iterator i = table.find( funcName );
    8988                if ( i == table.end() ) {
     89                        if ( isPrefix( funcName, "?`" ) ) {
     90                                // handle literal suffixes, which are user-defined postfix operators
     91                                info.inputName = funcName;
     92                                info.symbol = funcName.substr(2);
     93                                info.outputName = toString( "__operator_literal_", info.symbol );
     94                                info.type = OT_POSTFIX;
     95                                return true;
     96                        }
    9097                        return false;
    9198                } else {
  • src/Common/SemanticError.cc

    r800d275 r235b41f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 07:21:25 2015
    13 // Update Count     : 1
     12// Last Modified On : Tue Aug 29 18:17:35 2017
     13// Update Count     : 3
    1414//
    1515
    16 #include <cstdio>            // for fileno, stderr
    17 #include <unistd.h>          // for isatty
    18 #include <iostream>          // for basic_ostream, operator<<, ostream
    19 #include <list>              // for list, _List_iterator
    20 #include <string>            // for string, operator<<, operator+, to_string
     16#include <cstdio>                                                                               // for fileno, stderr
     17#include <unistd.h>                                                                             // for isatty
     18#include <iostream>                                                                             // for basic_ostream, operator<<, ostream
     19#include <list>                                                                                 // for list, _List_iterator
     20#include <string>                                                                               // for string, operator<<, operator+, to_string
    2121
    22 #include "Common/utility.h"  // for to_string, CodeLocation (ptr only)
     22#include "Common/utility.h"                                                             // for to_string, CodeLocation (ptr only)
    2323#include "SemanticError.h"
    24 
    25 inline const std::string& error_str() {
    26         static std::string str = isatty( fileno(stderr) ) ? "\e[31merror:\e[39m " : "error: ";
    27         return str;
    28 }
    2924
    3025SemanticError::SemanticError() {
     
    4944void SemanticError::print( std::ostream &os ) {
    5045        using std::to_string;
    51         for(auto err : errors) {
    52                 os << to_string( err.location ) << err.description << '\n';
     46        for( auto err : errors ) {
     47                os << to_string( err.location ) << err.description << std::endl;
    5348        }
    5449}
  • src/Common/SemanticError.h

    r800d275 r235b41f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 17 14:01:00 2017
    13 // Update Count     : 7
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Aug 29 22:03:36 2017
     13// Update Count     : 17
    1414//
    1515
    1616#pragma once
    1717
    18 #include <exception>  // for exception
    19 #include <iostream>   // for ostream
    20 #include <list>       // for list
    21 #include <string>     // for string
     18#include <exception>                                                                    // for exception
     19#include <iostream>                                                                             // for ostream
     20#include <list>                                                                                 // for list
     21#include <string>                                                                               // for string
     22#include <unistd.h>                                                                             // for isatty
    2223
    23 #include "CodeLocation.h"  // for CodeLocation, toString
     24#include "CodeLocation.h"                                                               // for CodeLocation, toString
    2425
    2526struct error {
     
    2829
    2930        error() = default;
    30         error( const std::string& str ) : description( str ) {}
     31        error( const std::string & str ) : description( str ) {}
    3132
    32         void maybeSet( const CodeLocation& location ) {
     33        void maybeSet( const CodeLocation & location ) {
    3334                if( this->location.linenumber < 0 ) {
    3435                        this->location = location;
     
    4142        SemanticError();
    4243        SemanticError( std::string error );
    43         template< typename T > SemanticError( const std::string &error, const T *obj );
     44        template< typename T > SemanticError( const std::string & error, const T * obj );
    4445        ~SemanticError() throw() {}
    4546
    46         void append( SemanticError &other );
     47        static inline const std::string & error_str() {
     48                static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
     49                return str;
     50        }
     51
     52        void append( SemanticError & other );
    4753        void append( const std::string & );
    4854        bool isEmpty() const;
    49         void print( std::ostream &os );
     55        void print( std::ostream & os );
    5056
    51         void set_location( const CodeLocation& location );
    52         // constructs an exception using the given message and the printed
    53         // representation of the obj (T must have a print method)
     57        void set_location( const CodeLocation & location );
     58        // constructs an exception using the given message and the printed representation of the obj (T must have a print
     59        // method)
    5460  private:
    5561        std::list< error > errors;
     
    5763
    5864template< typename T >
    59 SemanticError::SemanticError( const std::string &error, const T *obj ) {
     65SemanticError::SemanticError( const std::string & error, const T * obj ) {
    6066        append( toString( error, obj ) );
    6167}
  • src/Common/utility.h

    r800d275 r235b41f  
    174174}
    175175
     176template <typename E, typename UnaryPredicate, template< typename, typename...> class Container, typename... Args >
     177void filter( Container< E *, Args... > & container, UnaryPredicate pred, bool doDelete ) {
     178        auto i = begin( container );
     179        while ( i != end( container ) ) {
     180                auto it = next( i );
     181                if ( pred( *i ) ) {
     182                        if ( doDelete ) {
     183                                delete *i;
     184                        } // if
     185                        container.erase( i );
     186                } // if
     187                i = it;
     188        } // while
     189}
     190
    176191template< typename... Args >
    177192auto zip(Args&&... args) -> decltype(zipWith(std::forward<Args>(args)..., std::make_pair)) {
     
    207222        std::cerr << "Warning: ";
    208223        warn_single( params... );
     224}
     225
     226/// determines if `pref` is a prefix of `str`
     227static inline bool isPrefix( const std::string & str, const std::string & pref ) {
     228        if ( pref.size() > str.size() ) return false;
     229        auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
     230        return its.first == pref.end();
    209231}
    210232
  • src/GenPoly/Box.cc

    r800d275 r235b41f  
    141141                        virtual StructDecl *mutate( StructDecl *structDecl ) override;
    142142                        virtual UnionDecl *mutate( UnionDecl *unionDecl ) override;
     143                        virtual TraitDecl *mutate( TraitDecl *unionDecl ) override;
    143144                        virtual TypeDecl *mutate( TypeDecl *typeDecl ) override;
    144145                        virtual TypedefDecl *mutate( TypedefDecl *typedefDecl ) override;
     
    216217                  private:
    217218                };
    218 
    219219        } // anonymous namespace
    220220
     
    896896                                addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars );
    897897                                bodyStmt = new ExprStmt( noLabels, adapteeApp );
    898 //                      } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    899898                        } else if ( isDynType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
    900899                                // return type T
     
    12991298                }
    13001299
    1301                 /// determines if `pref` is a prefix of `str`
    1302                 bool isPrefix( const std::string & str, const std::string & pref ) {
    1303                         if ( pref.size() > str.size() ) return false;
    1304                         auto its = std::mismatch( pref.begin(), pref.end(), str.begin() );
    1305                         return its.first == pref.end();
    1306                 }
    1307 
    13081300                DeclarationWithType * Pass2::mutate( FunctionDecl *functionDecl ) {
    13091301                        functionDecl = safe_dynamic_cast< FunctionDecl * > ( handleDecl( functionDecl ) );
     
    13521344                }
    13531345
     1346                TraitDecl * Pass2::mutate( TraitDecl *aggDecl ) {
     1347                        return handleAggDecl( aggDecl );
     1348                }
     1349
    13541350                TypeDecl * Pass2::mutate( TypeDecl *typeDecl ) {
    13551351                        addToTyVarMap( typeDecl, scopeTyVars );
     
    13771373                Type *Pass2::mutate( FunctionType *funcType ) {
    13781374                        scopeTyVars.beginScope();
     1375
    13791376                        makeTyVarMap( funcType, scopeTyVars );
    13801377
     
    15501547                                        // (alloca was previously used, but can't be safely used in loops)
    15511548                                        Type *declType = objectDecl->get_type();
    1552                                         std::string bufName = bufNamer.newName();
    1553                                         ObjectDecl *newBuf = new ObjectDecl( bufName, Type::StorageClasses(), LinkageSpec::C, 0,
     1549                                        ObjectDecl *newBuf = new ObjectDecl( bufNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0,
    15541550                                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ),
    1555                                                 true, false, std::list<Attribute*>{ new Attribute( std::string{"aligned"}, std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
     1551                                                true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 );
    15561552                                        stmtsToAdd.push_back( new DeclStmt( noLabels, newBuf ) );
    15571553
    15581554                                        delete objectDecl->get_init();
    1559 
    1560                                         objectDecl->set_init( new SingleInit( new NameExpr( bufName ) ) );
     1555                                        objectDecl->set_init( new SingleInit( new VariableExpr( newBuf ) ) );
    15611556                                }
    15621557                        }
  • src/GenPoly/GenPoly.cc

    r800d275 r235b41f  
    336336                                assertf(bparam, "Aggregate parameters should be type expressions");
    337337
    338                                 // xxx - might need to let VoidType be a wildcard here too; could have some voids 
     338                                // xxx - might need to let VoidType be a wildcard here too; could have some voids
    339339                                // stuffed in for dtype-statics.
    340340                                // if ( is<VoidType>( aparam->get_type() ) || is<VoidType>( bparam->get_type() ) ) continue;
    341341                                if ( ! typesPolyCompatible( aparam->get_type(), bparam->get_type() ) ) return false;
    342342                        }
    343                        
     343
    344344                        return true;
    345345                }
     
    350350                // polymorphic types always match
    351351                if ( aid == type_index{typeid(TypeInstType)} ) return true;
    352                
     352
    353353                type_index bid{ typeid(*b) };
    354354                // polymorphic types always match
    355355                if ( bid == type_index{typeid(TypeInstType)} ) return true;
    356                
     356
    357357                // can't match otherwise if different types
    358358                if ( aid != bid ) return false;
     
    377377                                ConstantExpr *ad = dynamic_cast<ConstantExpr*>( aa->get_dimension() );
    378378                                ConstantExpr *bd = dynamic_cast<ConstantExpr*>( ba->get_dimension() );
    379                                 if ( ad && bd 
     379                                if ( ad && bd
    380380                                                && ad->get_constant()->get_value() != bd->get_constant()->get_value() )
    381381                                        return false;
     
    433433
    434434        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
     435                // xxx - should this actually be insert?
    435436                tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
    436437        }
  • src/InitTweak/FixInit.cc

    r800d275 r235b41f  
    127127
    128128                        // don't go into other functions
    129                         virtual void visit( __attribute__((unused)) FunctionDecl *decl ) override {}
     129                        virtual void visit( FunctionDecl * ) override {}
    130130
    131131                  protected:
     
    913913                // of the error.  See C++ Reference 6.6 Jump Statements for details.
    914914                void InsertDtors::handleGoto( BranchStmt * stmt ) {
    915                         assert( stmt->get_target() != "" && "BranchStmt missing a label" );
     915                        // can't do anything for computed goto
     916                        if ( stmt->computedTarget ) return;
     917
     918                        assertf( stmt->get_target() != "", "BranchStmt missing a label: %s", toString( stmt ).c_str() );
    916919                        // S_L = lvars = set of objects in scope at label definition
    917920                        // S_G = curVars = set of objects in scope at goto statement
  • src/InitTweak/InitTweak.cc

    r800d275 r235b41f  
    497497                using Visitor::visit;
    498498
    499                 virtual void visit( __attribute((unused)) ApplicationExpr *applicationExpr ) { isConstExpr = false; }
    500                 virtual void visit( __attribute((unused)) UntypedExpr *untypedExpr ) { isConstExpr = false; }
    501                 virtual void visit( NameExpr *nameExpr ) {
    502                         // xxx - temporary hack, because 0 and 1 really should be constexprs, even though they technically aren't in Cforall today
    503                         if ( nameExpr->get_name() != "0" && nameExpr->get_name() != "1" ) isConstExpr = false;
    504                 }
     499                virtual void visit( ApplicationExpr * ) { isConstExpr = false; }
     500                virtual void visit( UntypedExpr * ) { isConstExpr = false; }
     501                virtual void visit( NameExpr * ) { isConstExpr = false; }
    505502                // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
    506503                virtual void visit( AddressExpr *addressExpr ) {
     
    509506                        if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
    510507                }
    511                 virtual void visit( __attribute((unused)) LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
    512                 virtual void visit( __attribute((unused)) UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
    513                 virtual void visit( __attribute((unused)) MemberExpr *memberExpr ) { isConstExpr = false; }
    514                 virtual void visit( __attribute((unused)) VariableExpr *variableExpr ) { isConstExpr = false; }
     508                virtual void visit( UntypedMemberExpr * ) { isConstExpr = false; }
     509                virtual void visit( MemberExpr * ) { isConstExpr = false; }
     510                virtual void visit( VariableExpr * ) { isConstExpr = false; }
    515511                // these might be okay?
    516512                // virtual void visit( SizeofExpr *sizeofExpr );
     
    523519                // virtual void visit( LogicalExpr *logicalExpr );
    524520                // virtual void visit( ConditionalExpr *conditionalExpr );
    525                 virtual void visit( __attribute((unused)) TypeExpr *typeExpr ) { isConstExpr = false; }
    526                 virtual void visit( __attribute((unused)) AsmExpr *asmExpr ) { isConstExpr = false; }
    527                 virtual void visit( __attribute((unused)) UntypedValofExpr *valofExpr ) { isConstExpr = false; }
    528                 virtual void visit( __attribute((unused)) CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
    529                 virtual void visit( __attribute((unused)) UntypedTupleExpr *tupleExpr ) { isConstExpr = false; }
    530                 virtual void visit( __attribute((unused)) TupleExpr *tupleExpr ) { isConstExpr = false; }
    531                 virtual void visit( __attribute((unused)) TupleAssignExpr *tupleExpr ) { isConstExpr = false; }
     521                virtual void visit( TypeExpr * ) { isConstExpr = false; }
     522                virtual void visit( AsmExpr * ) { isConstExpr = false; }
     523                virtual void visit( UntypedValofExpr * ) { isConstExpr = false; }
     524                virtual void visit( CompoundLiteralExpr * ) { isConstExpr = false; }
     525                virtual void visit( UntypedTupleExpr * ) { isConstExpr = false; }
     526                virtual void visit( TupleExpr * ) { isConstExpr = false; }
     527                virtual void visit( TupleAssignExpr * ) { isConstExpr = false; }
    532528
    533529                bool isConstExpr;
  • src/Parser/ExpressionNode.cc

    r800d275 r235b41f  
    77// ExpressionNode.cc --
    88//
    9 // Author           : Rodolfo G. Esteves
     9// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 13:17:07 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  2 11:12:00 2017
    13 // Update Count     : 568
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Sep  3 22:21:21 2017
     13// Update Count     : 639
    1414//
    1515
     
    5858static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    5959
    60 Expression * build_constantInteger( const std::string & str ) {
     60static void sepNumeric( string & str, string & units ) {
     61        string::size_type posn = str.find_first_of( "`" );
     62        if ( posn != string::npos ) {
     63                units = "?" + str.substr( posn );                               // extract units
     64                str.erase( posn );                                                              // remove units
     65        } // if
     66} // sepNumeric
     67
     68Expression * build_constantInteger( string & str ) {
    6169        static const BasicType::Kind kind[2][3] = {
    6270                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
    6371                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
    6472        };
     73
     74        string units;                                                                           // units
     75        sepNumeric( str, units );                                                       // separate constant from units
     76
    6577        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    6678        int size;                                                                                       // 0 => int, 1 => long, 2 => long long
     
    6981        Expression * ret;
    7082
     83        // ROB: what do we do with units on 0 and 1?
    7184        // special constants
    7285        if ( str == "0" ) {
     
    134147        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    135148  CLEANUP:
     149        if ( units.length() != 0 ) {
     150                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     151        } // if
     152
    136153        delete &str;                                                                            // created by lex
    137154        return ret;
    138155} // build_constantInteger
    139156
    140 Expression * build_constantFloat( const std::string & str ) {
     157Expression * build_constantFloat( string & str ) {
    141158        static const BasicType::Kind kind[2][3] = {
    142159                { BasicType::Float, BasicType::Double, BasicType::LongDouble },
    143160                { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    144161        };
     162
     163        string units;                                                                           // units
     164        sepNumeric( str, units );                                                       // separate constant from units
    145165
    146166        bool complx = false;                                                            // real, complex
     
    169189
    170190        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
     191        if ( units.length() != 0 ) {
     192                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     193        } // if
     194
    171195        delete &str;                                                                            // created by lex
    172196        return ret;
    173197} // build_constantFloat
    174198
    175 Expression * build_constantChar( const std::string & str ) {
     199static void sepString( string & str, string & units, char delimit ) {
     200        string::size_type posn = str.find_last_of( delimit ) + 1;
     201        if ( posn != str.length() ) {
     202                units = "?" + str.substr( posn );                               // extract units
     203                str.erase( posn );                                                              // remove units
     204        } // if
     205} // sepString
     206
     207Expression * build_constantChar( string & str ) {
     208        string units;                                                                           // units
     209        sepString( str, units, '\'' );                                          // separate constant from units
     210
    176211        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
     212        if ( units.length() != 0 ) {
     213                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     214        } // if
     215
    177216        delete &str;                                                                            // created by lex
    178217        return ret;
    179218} // build_constantChar
    180219
    181 ConstantExpr * build_constantStr( const std::string & str ) {
    182         // string should probably be a primitive type
    183         ArrayType * at = new ArrayType( noQualifiers, new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
    184                                                                    new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    185                                                                    false, false );
    186         ConstantExpr * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
     220Expression * build_constantStr( string & str ) {
     221        string units;                                                                           // units
     222        sepString( str, units, '"' );                                           // separate constant from units
     223
     224        BasicType::Kind strtype = BasicType::Char;                      // default string type
     225        switch ( str[0] ) {                                                                     // str has >= 2 characters, i.e, null string ""
     226          case 'u':
     227                if ( str[1] == '8' ) break;                                             // utf-8 characters
     228                strtype = BasicType::ShortUnsignedInt;
     229                break;
     230          case 'U':
     231                strtype = BasicType::UnsignedInt;
     232                break;
     233          case 'L':
     234                strtype = BasicType::SignedInt;
     235                break;
     236        } // switch
     237        ArrayType * at = new ArrayType( noQualifiers, new BasicType( Type::Qualifiers( Type::Const ), strtype ),
     238                                                                        new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
     239                                                                        false, false );
     240        Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
     241        if ( units.length() != 0 ) {
     242                ret = new UntypedExpr( new NameExpr( units ), { ret } );
     243        } // if
     244
    187245        delete &str;                                                                            // created by lex
    188246        return ret;
    189247} // build_constantStr
    190248
    191 Expression * build_field_name_FLOATINGconstant( const std::string & str ) {
     249Expression * build_field_name_FLOATINGconstant( const string & str ) {
    192250        // str is of the form A.B -> separate at the . and return member expression
    193251        int a, b;
    194252        char dot;
    195         std::stringstream ss( str );
     253        stringstream ss( str );
    196254        ss >> a >> dot >> b;
    197255        UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
     
    207265                } else {
    208266                        return new UntypedMemberExpr( fracts, fieldName );
    209                 }
    210         }
     267                } // if
     268        } // if
    211269        return fieldName;
    212270} // make_field_name_fraction_constants
     
    216274} // build_field_name_fraction_constants
    217275
    218 Expression * build_field_name_REALFRACTIONconstant( const std::string & str ) {
     276Expression * build_field_name_REALFRACTIONconstant( const string & str ) {
    219277        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
    220         Expression * ret = build_constantInteger( *new std::string( str.substr(1) ) );
     278        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
    221279        delete &str;
    222280        return ret;
    223281} // build_field_name_REALFRACTIONconstant
    224282
    225 Expression * build_field_name_REALDECIMALconstant( const std::string & str ) {
     283Expression * build_field_name_REALDECIMALconstant( const string & str ) {
    226284        if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
    227         Expression * ret = build_constantInteger( *new std::string( str.substr( 0, str.size()-1 ) ) );
     285        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
    228286        delete &str;
    229287        return ret;
     
    236294} // build_varref
    237295
    238 
     296// TODO: get rid of this and OperKinds and reuse code from OperatorTable
    239297static const char * OperName[] = {                                              // must harmonize with OperKinds
    240298        // diadic
     
    244302        "?[?]", "...",
    245303        // monadic
    246         "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
     304        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--",
    247305}; // OperName
    248306
     
    307365
    308366Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
    309         std::list< Expression * > args;
     367        list< Expression * > args;
    310368        args.push_back( maybeMoveBuild< Expression >(expr_node) );
    311369        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     
    313371
    314372Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
    315         std::list< Expression * > args;
    316         args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx
     373        list< Expression * > args;
     374        args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
    317375        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    318376} // build_unary_ptr
    319377
    320378Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    321         std::list< Expression * > args;
     379        list< Expression * > args;
    322380        args.push_back( maybeMoveBuild< Expression >(expr_node1) );
    323381        args.push_back( maybeMoveBuild< Expression >(expr_node2) );
     
    326384
    327385Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    328         std::list< Expression * > args;
     386        list< Expression * > args;
    329387        args.push_back( maybeMoveBuild< Expression >(expr_node1) );
    330388        args.push_back( maybeMoveBuild< Expression >(expr_node2) );
     
    349407
    350408Expression * build_tuple( ExpressionNode * expr_node ) {
    351         std::list< Expression * > exprs;
     409        list< Expression * > exprs;
    352410        buildMoveList( expr_node, exprs );
    353411        return new UntypedTupleExpr( exprs );;
     
    355413
    356414Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
    357         std::list< Expression * > args;
     415        list< Expression * > args;
    358416        buildMoveList( expr_node, args );
    359417        return new UntypedExpr( maybeMoveBuild< Expression >(function), args, nullptr );
     
    364422} // build_range
    365423
    366 Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand ) {
     424Expression * build_asmexpr( ExpressionNode * inout, Expression * constraint, ExpressionNode * operand ) {
    367425        return new AsmExpr( maybeMoveBuild< Expression >( inout ), constraint, maybeMoveBuild< Expression >(operand) );
    368426} // build_asmexpr
  • src/Parser/ParseNode.h

    r800d275 r235b41f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 17 13:46:00 2017
    13 // Update Count     : 795
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Sep  3 19:24:34 2017
     13// Update Count     : 799
    1414//
    1515
     
    154154        Index, Range,
    155155        // monadic
    156         UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
     156        UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost,
    157157        Ctor, Dtor,
    158158}; // OperKinds
     
    162162};
    163163
    164 Expression * build_constantInteger( const std::string &str );
    165 Expression * build_constantFloat( const std::string &str );
    166 Expression * build_constantChar( const std::string &str );
    167 ConstantExpr * build_constantStr( const std::string &str );
     164Expression * build_constantInteger( std::string &str );
     165Expression * build_constantFloat( std::string &str );
     166Expression * build_constantChar( std::string &str );
     167Expression * build_constantStr( std::string &str );
    168168Expression * build_field_name_FLOATINGconstant( const std::string & str );
    169169Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
     
    197197Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
    198198Expression * build_range( ExpressionNode * low, ExpressionNode * high );
    199 Expression * build_asmexpr( ExpressionNode * inout, ConstantExpr * constraint, ExpressionNode * operand );
     199Expression * build_asmexpr( ExpressionNode * inout, Expression * constraint, ExpressionNode * operand );
    200200Expression * build_valexpr( StatementNode * s );
    201201Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
     
    330330        bool hasEllipsis;
    331331        LinkageSpec::Spec linkage;
    332         ConstantExpr *asmName;
     332        Expression *asmName;
    333333        std::list< Attribute * > attributes;
    334334        InitializerNode * initializer;
     
    413413Statement * build_finally( StatementNode * stmt );
    414414Statement * build_compound( StatementNode * first );
    415 Statement * build_asmstmt( bool voltile, ConstantExpr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
     415Statement * build_asmstmt( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    416416WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
    417417WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
  • src/Parser/StatementNode.cc

    r800d275 r235b41f  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 16:01:31 2017
    13 // Update Count     : 345
     12// Last Modified On : Fri Sep  1 23:25:23 2017
     13// Update Count     : 346
    1414//
    1515
     
    9999        } // if
    100100
    101         Expression * cond = ctl->condition ? maybeMoveBuild< Expression >(ctl->condition) : new VariableExpr( dynamic_cast<DeclarationWithType *>( dynamic_cast<DeclStmt *>( init.back() )->decl ) );
     101        Expression * cond = nullptr;
     102        if ( ctl->condition ) {
     103                // compare the provided condition against 0
     104                cond =  notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
     105        } else {
     106                for ( Statement * stmt : init ) {
     107                        // build the && of all of the declared variables compared against 0
     108                        DeclStmt * declStmt = safe_dynamic_cast< DeclStmt * >( stmt );
     109                        DeclarationWithType * dwt = safe_dynamic_cast< DeclarationWithType * >( declStmt->decl );
     110                        Expression * nze = notZeroExpr( new VariableExpr( dwt ) );
     111                        cond = cond ? new LogicalExpr( cond, nze, true ) : nze;
     112                }
     113        }
    102114        delete ctl;
    103         return new IfStmt( noLabels, notZeroExpr( cond ), thenb, elseb, init );
     115        return new IfStmt( noLabels, cond, thenb, elseb, init );
    104116}
    105117
     
    288300}
    289301
    290 Statement *build_asmstmt( bool voltile, ConstantExpr *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) {
     302Statement *build_asmstmt( bool voltile, Expression *instruction, ExpressionNode *output, ExpressionNode *input, ExpressionNode *clobber, LabelNode *gotolabels ) {
    291303        std::list< Expression * > out, in;
    292304        std::list< ConstantExpr * > clob;
  • src/Parser/TypeData.cc

    r800d275 r235b41f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:41:00 2017
    13 // Update Count     : 568
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Sep  1 23:13:38 2017
     13// Update Count     : 569
    1414//
    1515
     
    814814} // buildTypeof
    815815
    816 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, ConstantExpr *asmName, Initializer * init, std::list< Attribute * > attributes ) {
     816Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
    817817        if ( td->kind == TypeData::Function ) {
    818818                if ( td->function.idList ) {                                    // KR function ?
  • src/Parser/TypeData.h

    r800d275 r235b41f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:18:36 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:38:00 2017
    13 // Update Count     : 189
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Sep  1 23:33:45 2017
     13// Update Count     : 190
    1414//
    1515
     
    118118TupleType * buildTuple( const TypeData * );
    119119TypeofType * buildTypeof( const TypeData * );
    120 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, ConstantExpr *asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
     120Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
    121121FunctionType * buildFunction( const TypeData * );
    122122void buildKRFunction( const TypeData::Function_t & function );
  • src/Parser/lex.ll

    r800d275 r235b41f  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Tue Aug 22 22:43:39 2017
    13  * Update Count     : 558
     12 * Last Modified On : Thu Aug 31 21:30:10 2017
     13 * Update Count     : 598
    1414 */
    1515
     
    1919
    2020%{
    21 // This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive have been
     21// The lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive have been
    2222// performed and removed from the source. The only exceptions are preprocessor directives passed to the compiler (e.g.,
    2323// line-number directives) and C/C++ style comments, which are ignored.
     
    2525//**************************** Includes and Defines ****************************
    2626
     27unsigned int column = 0;                                                                // position of the end of the last token parsed
     28#define YY_USER_ACTION column += yyleng;                                // trigger before each matching rule's action
     29
    2730#include <string>
    2831#include <cstdio>                                                                               // FILENAME_MAX
     32using namespace std;
    2933
    3034#include "ParseNode.h"
     
    3236
    3337char *yyfilename;
    34 std::string *strtext;                                                                   // accumulate parts of character and string constant value
     38string *strtext;                                                                                // accumulate parts of character and string constant value
    3539
    3640#define RETURN_LOCN(x)          yylval.tok.loc.file = yyfilename; yylval.tok.loc.line = yylineno; return( x )
    37 #define RETURN_VAL(x)           yylval.tok.str = new std::string( yytext ); RETURN_LOCN( x )
     41#define RETURN_VAL(x)           yylval.tok.str = new string( yytext ); RETURN_LOCN( x )
    3842#define RETURN_CHAR(x)          yylval.tok.str = nullptr; RETURN_LOCN( x )
    3943#define RETURN_STR(x)           yylval.tok.str = strtext; RETURN_LOCN( x )
    4044
    4145#define WHITE_RETURN(x)         // do nothing
    42 #define NEWLINE_RETURN()        WHITE_RETURN( '\n' )
     46#define NEWLINE_RETURN()        column = 0; WHITE_RETURN( '\n' )
    4347#define ASCIIOP_RETURN()        RETURN_CHAR( (int)yytext[0] ) // single character operator
    4448#define NAMEDOP_RETURN(x)       RETURN_CHAR( x )                        // multichar operator, with a name
     
    5357        yyleng = 0;
    5458        for ( int i = 0; yytext[i] != '\0'; i += 1 ) {
     59                if ( yytext[i] == '`' ) {
     60                        // copy user suffix
     61                        for ( ; yytext[i] != '\0'; i += 1 ) {
     62                                yytext[yyleng] = yytext[i];
     63                                yyleng += 1;
     64                        } // for
     65                        break;
     66                } // if
    5567                if ( yytext[i] != '_' ) {
    5668                        yytext[yyleng] = yytext[i];
     
    7789attr_identifier "@"{identifier}
    7890
     91user_suffix_opt ("`"{identifier})?
     92
    7993                                // numeric constants, CFA: '_' in constant
    8094hex_quad {hex}("_"?{hex}){3}
    81 integer_suffix "_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?)))
     95integer_suffix_opt ("_"?(([uU](("ll"|"LL"|[lL])[iI]|[iI]?("ll"|"LL"|[lL])?))|([iI](("ll"|"LL"|[lL])[uU]|[uU]?("ll"|"LL"|[lL])?))|(("ll"|"LL"|[lL])([iI][uU]|[uU]?[iI]?))))?
    8296
    8397octal_digits ({octal})|({octal}({octal}|"_")*{octal})
    8498octal_prefix "0""_"?
    85 octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix}?
     99octal_constant (("0")|({octal_prefix}{octal_digits})){integer_suffix_opt}{user_suffix_opt}
    86100
    87101nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
    88 decimal_constant {nonzero_digits}{integer_suffix}?
     102decimal_constant {nonzero_digits}{integer_suffix_opt}{user_suffix_opt}
    89103
    90104hex_digits ({hex})|({hex}({hex}|"_")*{hex})
    91105hex_prefix "0"[xX]"_"?
    92 hex_constant {hex_prefix}{hex_digits}{integer_suffix}?
    93 
     106hex_constant {hex_prefix}{hex_digits}{integer_suffix_opt}{user_suffix_opt}
     107
     108                                // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
     109floating_suffix_opt ("_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL"))?
    94110decimal_digits ({decimal})|({decimal}({decimal}|"_")*{decimal})
    95 real_decimal {decimal_digits}"."{exponent}?{floating_suffix}?
    96 real_fraction "."{decimal_digits}{exponent}?{floating_suffix}?
     111real_decimal {decimal_digits}"."{exponent}?{floating_suffix_opt}{user_suffix_opt}
     112real_fraction "."{decimal_digits}{exponent}?{floating_suffix_opt}{user_suffix_opt}
    97113real_constant {decimal_digits}{real_fraction}
    98114exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    99                                 // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
    100 floating_suffix "_"?([fFdDlL][iI]?|[iI][lLfFdD]?|"DL")
    101 floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix}?
     115floating_constant (({real_constant}{exponent}?)|({decimal_digits}{exponent})){floating_suffix_opt}{user_suffix_opt}
    102116
    103117binary_exponent "_"?[pP]"_"?[+-]?{decimal_digits}
    104118hex_fractional_constant ({hex_digits}?"."{hex_digits})|({hex_digits}".")
    105 hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix}?
     119hex_floating_constant {hex_prefix}(({hex_fractional_constant}{binary_exponent})|({hex_digits}{binary_exponent})){floating_suffix_opt}
    106120
    107121                                // character escape sequence, GCC: \e => esc character
     
    154168                memcpy( &filename, begin_string + 1, length );  // copy file name from yytext
    155169                filename[ length ] = '\0';                                              // terminate string with sentinel
    156                 //std::cout << "file " << filename << " line " << lineno << std::endl;
     170                //cout << "file " << filename << " line " << lineno << endl;
    157171                yylineno = lineno;
    158172                yyfilename = filename;
     
    302316
    303317                                /* character constant, allows empty value */
    304 ({cwide_prefix}[_]?)?['] { BEGIN QUOTE; rm_underscore(); strtext = new std::string( yytext, yyleng ); }
     318({cwide_prefix}[_]?)?['] { BEGIN QUOTE; rm_underscore(); strtext = new string( yytext, yyleng ); }
    305319<QUOTE>[^'\\\n]* { strtext->append( yytext, yyleng ); }
    306 <QUOTE>['\n]    { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
     320<QUOTE>['\n]{user_suffix_opt}   { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
    307321                                /* ' stop highlighting */
    308322
    309323                                /* string constant */
    310 ({swide_prefix}[_]?)?["] { BEGIN STRING; rm_underscore(); strtext = new std::string( yytext, yyleng ); }
     324({swide_prefix}[_]?)?["] { BEGIN STRING; rm_underscore(); strtext = new string( yytext, yyleng ); }
    311325<STRING>[^"\\\n]* { strtext->append( yytext, yyleng ); }
    312 <STRING>["\n]   { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
     326<STRING>["\n]{user_suffix_opt}  { BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
    313327                                /* " stop highlighting */
    314328
     
    383397{op_unary}"?"   { IDENTIFIER_RETURN(); }                                // unary
    384398"?"({op_unary_pre_post}|"()"|"[?]"|"{}") { IDENTIFIER_RETURN(); }
    385 "^?{}" { IDENTIFIER_RETURN(); }
     399"^?{}"                  { IDENTIFIER_RETURN(); }
     400"?`"{identifier} { IDENTIFIER_RETURN(); }                               // unit operator
    386401"?"{op_binary_over}"?"  { IDENTIFIER_RETURN(); }                // binary
    387402        /*
     
    422437}
    423438
    424                                 /* unknown characters */
    425 .                               { printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno); }
     439                                /* unknown character */
     440.                               { yyerror( "unknown character" ); }
    426441
    427442%%
     443// ----end of lexer----
     444
     445void yyerror( const char * errmsg ) {
     446        cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
     447                 << ": " << SemanticError::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
     448}
    428449
    429450// Local Variables: //
  • src/Parser/parser.yy

    r800d275 r235b41f  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 28 13:24:10 2017
    13 // Update Count     : 2720
     12// Last Modified On : Sun Sep  3 20:43:19 2017
     13// Update Count     : 2742
    1414//
    1515
     
    4848#include <cstdio>
    4949#include <stack>
     50using namespace std;
     51
    5052#include "ParseNode.h"
    5153#include "TypedefTable.h"
    5254#include "TypeData.h"
    5355#include "LinkageSpec.h"
    54 using namespace std;
     56#include "Common/SemanticError.h"                                               // error_str
    5557
    5658extern DeclarationNode * parseTree;
     
    98100        StatementNode * sn;
    99101        WaitForStmt * wfs;
    100         ConstantExpr * constant;
     102        Expression * constant;
    101103        IfCtl * ifctl;
    102104        ForCtl * fctl;
     
    534536                                $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
    535537                                break;
     538                          case OperKinds::And:
     539                                $$ = new ExpressionNode( new AddressExpr( build_addressOf( $2 ) ) );
     540                                break;
    536541                          default:
    537542                                assert( false );
     
    560565        | ATTR_IDENTIFIER '(' type ')'
    561566                { $$ = new ExpressionNode( build_attrtype( build_varref( $1 ), $3 ) ); }
    562 //      | ANDAND IDENTIFIER                                                                     // GCC, address of label
    563 //              { $$ = new ExpressionNode( new OperatorNode( OperKinds::LabelAddress ), new ExpressionNode( build_varref( $2 ) ); }
    564567        ;
    565568
     
    31333136// ----end of grammar----
    31343137
    3135 extern char *yytext;
    3136 
    3137 void yyerror( const char * ) {
    3138         if ( yyfilename ) {
    3139                 cout << yyfilename << ":";
    3140         } // if
    3141         cout << yylineno << ":1 syntax error at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << "\"" << endl;
    3142 }
    3143 
    31443138// Local Variables: //
    31453139// mode: c++ //
  • src/ResolvExpr/AlternativeFinder.cc

    r800d275 r235b41f  
    698698
    699699        void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
    700                 {
    701                         std::string fname = InitTweak::getFunctionName( untypedExpr );
    702                         if ( fname == "&&" ) {
    703                                 VoidType v = Type::Qualifiers();                // resolve to type void *
    704                                 PointerType pt( Type::Qualifiers(), v.clone() );
    705                                 UntypedExpr *vexpr = untypedExpr->clone();
    706                                 vexpr->set_result( pt.clone() );
    707                                 alternatives.push_back( Alternative( vexpr, env, Cost::zero) );
    708                                 return;
    709                         }
    710                 }
    711 
    712700                AlternativeFinder funcFinder( indexer, env );
    713701                funcFinder.findWithAdjustment( untypedExpr->get_function() );
     
    749737                                if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
    750738                                        if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    751                                                 referenceToRvalueConversion( func->expr );
     739                                                Alternative newFunc( *func );
     740                                                referenceToRvalueConversion( newFunc.expr );
    752741                                                for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    753742                                                        // XXX
    754743                                                        //Designators::check_alternative( function, *actualAlt );
    755                                                         makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     744                                                        makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
    756745                                                }
    757746                                        }
    758747                                } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
    759                                         referenceToRvalueConversion( func->expr );
    760748                                        EqvClass eqvClass;
    761749                                        if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
    762750                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
     751                                                        Alternative newFunc( *func );
     752                                                        referenceToRvalueConversion( newFunc.expr );
    763753                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    764                                                                 makeFunctionAlternatives( *func, function, *actualAlt, std::back_inserter( candidates ) );
     754                                                                makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) );
    765755                                                        } // for
    766756                                                } // if
     
    773763                                        if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) {
    774764                                                if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
    775                                                         referenceToRvalueConversion( funcOp->expr );
     765                                                        Alternative newFunc( *funcOp );
     766                                                        referenceToRvalueConversion( newFunc.expr );
    776767                                                        for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) {
    777768                                                                AltList currentAlt;
    778769                                                                currentAlt.push_back( *func );
    779770                                                                currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() );
    780                                                                 makeFunctionAlternatives( *funcOp, function, currentAlt, std::back_inserter( candidates ) );
     771                                                                makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) );
    781772                                                        } // for
    782773                                                } // if
     
    853844                        } // if
    854845                } // for
     846        }
     847
     848        void AlternativeFinder::visit( LabelAddressExpr * expr ) {
     849                alternatives.push_back( Alternative( expr->clone(), env, Cost::zero) );
    855850        }
    856851
  • src/ResolvExpr/AlternativeFinder.h

    r800d275 r235b41f  
    5454                virtual void visit( UntypedExpr *untypedExpr );
    5555                virtual void visit( AddressExpr *addressExpr );
     56                virtual void visit( LabelAddressExpr *labelExpr );
    5657                virtual void visit( CastExpr *castExpr );
    5758                virtual void visit( VirtualCastExpr *castExpr );
  • src/ResolvExpr/RenameVars.cc

    r800d275 r235b41f  
    8888                typeBefore( aggregateUseType );
    8989                acceptAll( aggregateUseType->get_parameters(), *this );
    90                 acceptAll( aggregateUseType->get_members(), *this );
    9190                typeAfter( aggregateUseType );
    9291        }
  • src/ResolvExpr/TypeEnvironment.cc

    r800d275 r235b41f  
    2525
    2626namespace ResolvExpr {
    27         // adding this comparison operator significantly improves assertion resolution run time for
    28         // some cases. The current resolution algorithm's speed partially depends on the order of
    29         // assertions. Assertions which have fewer possible matches should appear before
    30         // assertions which have more possible matches. This seems to imply that this could
    31         // be further improved by providing an indexer as an additional argument and ordering based
    32         // on the number of matches of the same kind (object, function) for the names of the
    33         // declarations.
    34         //
    35         // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
    36         bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {
    37                         // Objects are always less than functions
    38                         if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {
    39                                 if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {
    40                                         // objects are ordered by name then type pointer, in that order
    41                                         int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );
    42                                         return cmp < 0 ||
    43                                                 ( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );
    44                                 } else {
    45                                         return true;
    46                                 }
    47                         } else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {
    48                                 if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {
    49                                         // functions are ordered by name, # parameters, # returnVals, type pointer in that order
    50                                         FunctionType * ftype1 = funcDecl1->get_functionType();
    51                                         FunctionType * ftype2 = funcDecl2->get_functionType();
    52                                         int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();
    53                                         int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();
    54                                         if ( numThings1 < numThings2 ) return true;
    55                                         if ( numThings1 > numThings2 ) return false;
    56 
    57                                         // if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;
    58                                         // else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;
    59                                         // // same number of parameters
    60                                         // if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;
    61                                         // else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;
    62                                         // same number of return vals
    63                                         // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );
    64                                         // if ( cmp < 0 ) return true;
    65                                         // else if ( cmp > 0 ) return false;
    66                                         // // same name
    67                                         return ftype1 < ftype2;
    68                                 } else {
    69                                         return false;
    70                                 }
    71                         } else {
    72                                 assert( false );
    73                         }
    74                 }
    75 
    7627        void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) {
    7728                for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) {
  • src/ResolvExpr/TypeEnvironment.h

    r800d275 r235b41f  
    2828
    2929namespace ResolvExpr {
     30        // adding this comparison operator significantly improves assertion resolution run time for
     31        // some cases. The current resolution algorithm's speed partially depends on the order of
     32        // assertions. Assertions which have fewer possible matches should appear before
     33        // assertions which have more possible matches. This seems to imply that this could
     34        // be further improved by providing an indexer as an additional argument and ordering based
     35        // on the number of matches of the same kind (object, function) for the names of the
     36        // declarations.
     37        //
     38        // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
    3039        struct AssertCompare {
    31                 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const;
     40                bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {
     41                        int cmp = d1->get_name().compare( d2->get_name() );
     42                        return cmp < 0 ||
     43                                ( cmp == 0 && d1->get_type() < d2->get_type() );
     44                }
    3245        };
    3346        struct AssertionSetValue {
  • src/SymTab/Indexer.cc

    r800d275 r235b41f  
    398398        void Indexer::visit( LabelAddressExpr *labAddressExpr ) {
    399399                acceptNewScope( labAddressExpr->get_result(), *this );
    400                 maybeAccept( labAddressExpr->get_arg(), *this );
    401400        }
    402401
     
    554553
    555554
    556         void Indexer::visit( TraitInstType *contextInst ) {
    557                 acceptAll( contextInst->get_parameters(), *this );
    558                 acceptAll( contextInst->get_members(), *this );
     555        void Indexer::visit( TraitInstType *traitInst ) {
     556                acceptAll( traitInst->get_parameters(), *this );
    559557        }
    560558
  • src/SymTab/Validate.cc

    r800d275 r235b41f  
    127127          public:
    128128                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    129                 using Parent::visit;
     129                using Parent::visit;
     130                void visit( TypeInstType *typeInst ) final;
     131
    130132                void visit( EnumInstType *enumInst ) final;
    131133                void visit( StructInstType *structInst ) final;
    132134                void visit( UnionInstType *unionInst ) final;
    133                 void visit( TraitInstType *contextInst ) final;
     135                void visit( TraitInstType *traitInst ) final;
     136
    134137                void visit( EnumDecl *enumDecl ) final;
    135138                void visit( StructDecl *structDecl ) final;
    136139                void visit( UnionDecl *unionDecl ) final;
    137                 void visit( TypeInstType *typeInst ) final;
     140                void visit( TraitDecl * traitDecl ) final;
     141
    138142          private:
    139143                const Indexer *indexer;
     
    240244        };
    241245
     246        struct LabelAddressFixer final : public WithGuards {
     247                std::set< Label > labels;
     248
     249                void premutate( FunctionDecl * funcDecl );
     250                Expression * postmutate( AddressExpr * addrExpr );
     251        };
    242252
    243253        FunctionDecl * dereferenceOperator = nullptr;
     
    253263                PassVisitor<ValidateGenericParameters> genericParams;
    254264                PassVisitor<FindSpecialDeclarations> finder;
     265                PassVisitor<LabelAddressFixer> labelAddrFixer;
    255266
    256267                EliminateTypedef::eliminateTypedef( translationUnit );
     
    270281                ArrayLength::computeLength( translationUnit );
    271282                acceptAll( translationUnit, finder );
     283                mutateAll( translationUnit, labelAddrFixer );
    272284        }
    273285
     
    287299
    288300        HoistStruct::HoistStruct() : inStruct( false ) {
    289         }
    290 
    291         void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {
    292                 std::list< Declaration * >::iterator i = declList.begin();
    293                 while ( i != declList.end() ) {
    294                         std::list< Declaration * >::iterator next = i;
    295                         ++next;
    296                         if ( pred( *i ) ) {
    297                                 if ( doDelete ) {
    298                                         delete *i;
    299                                 } // if
    300                                 declList.erase( i );
    301                         } // if
    302                         i = next;
    303                 } // while
    304301        }
    305302
     
    453450        }
    454451
    455         void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     452        template< typename Decl >
     453        void normalizeAssertions( std::list< Decl * > & assertions ) {
     454                // ensure no duplicate trait members after the clone
     455                auto pred = [](Decl * d1, Decl * d2) {
     456                        // only care if they're equal
     457                        DeclarationWithType * dwt1 = dynamic_cast<DeclarationWithType *>( d1 );
     458                        DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
     459                        if ( dwt1 && dwt2 ) {
     460                                if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
     461                                        // std::cerr << "=========== equal:" << std::endl;
     462                                        // std::cerr << "d1: " << d1 << std::endl;
     463                                        // std::cerr << "d2: " << d2 << std::endl;
     464                                        return false;
     465                                }
     466                        }
     467                        return d1 < d2;
     468                };
     469                std::set<Decl *, decltype(pred)> unique_members( assertions.begin(), assertions.end(), pred );
     470                // if ( unique_members.size() != assertions.size() ) {
     471                //      std::cerr << "============different" << std::endl;
     472                //      std::cerr << unique_members.size() << " " << assertions.size() << std::endl;
     473                // }
     474
     475                std::list< Decl * > order;
     476                order.splice( order.end(), assertions );
     477                std::copy_if( order.begin(), order.end(), back_inserter( assertions ), [&]( Decl * decl ) {
     478                        return unique_members.count( decl );
     479                });
     480        }
     481
     482        // expand assertions from trait instance, performing the appropriate type variable substitutions
     483        template< typename Iterator >
     484        void expandAssertions( TraitInstType * inst, Iterator out ) {
     485                assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
     486                std::list< DeclarationWithType * > asserts;
     487                for ( Declaration * decl : inst->baseTrait->members ) {
     488                        asserts.push_back( safe_dynamic_cast<DeclarationWithType *>( decl->clone() ) );
     489                }
     490                // substitute trait decl parameters for instance parameters
     491                applySubstitution( inst->baseTrait->parameters.begin(), inst->baseTrait->parameters.end(), inst->parameters.begin(), asserts.begin(), asserts.end(), out );
     492        }
     493
     494        void LinkReferenceToTypes::visit( TraitDecl * traitDecl ) {
     495                Parent::visit( traitDecl );
     496
     497                if ( traitDecl->name == "sized" ) {
     498                        // "sized" is a special trait - flick the sized status on for the type variable
     499                        assertf( traitDecl->parameters.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", traitDecl->parameters.size() );
     500                        TypeDecl * td = traitDecl->parameters.front();
     501                        td->set_sized( true );
     502                }
     503
     504                // move assertions from type parameters into the body of the trait
     505                for ( TypeDecl * td : traitDecl->parameters ) {
     506                        for ( DeclarationWithType * assert : td->assertions ) {
     507                                if ( TraitInstType * inst = dynamic_cast< TraitInstType * >( assert->get_type() ) ) {
     508                                        expandAssertions( inst, back_inserter( traitDecl->members ) );
     509                                } else {
     510                                        traitDecl->members.push_back( assert->clone() );
     511                                }
     512                        }
     513                        deleteAll( td->assertions );
     514                        td->assertions.clear();
     515                } // for
     516        }
     517
     518        void LinkReferenceToTypes::visit( TraitInstType * traitInst ) {
    456519                Parent::visit( traitInst );
    457                 if ( traitInst->get_name() == "sized" ) {
    458                         // "sized" is a special trait with no members - just flick the sized status on for the type variable
    459                         if ( traitInst->get_parameters().size() != 1 ) {
    460                                 throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    461                         }
    462                         TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
    463                         TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
    464                         TypeDecl * decl = inst->get_baseType();
    465                         decl->set_sized( true );
    466                         // since "sized" is special, the next few steps don't apply
    467                         return;
    468                 }
    469 
    470520                // handle other traits
    471                 TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
     521                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->name );
    472522                if ( ! traitDecl ) {
    473                         throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
     523                        throw SemanticError( "use of undeclared trait " + traitInst->name );
    474524                } // if
    475525                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    476526                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    477527                } // if
    478 
    479                 for ( TypeDecl * td : traitDecl->get_parameters() ) {
    480                         for ( DeclarationWithType * assert : td->get_assertions() ) {
    481                                 traitInst->get_members().push_back( assert->clone() );
    482                         } // for
    483                 } // for
    484 
    485                 // need to clone members of the trait for ownership purposes
    486                 std::list< Declaration * > members;
    487                 std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
    488 
    489                 applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
     528                traitInst->baseTrait = traitDecl;
    490529
    491530                // need to carry over the 'sized' status of each decl in the instance
     
    498537                        }
    499538                }
     539                // normalizeAssertions( traitInst->members );
    500540        }
    501541
     
    561601        void forallFixer( Type * func ) {
    562602                for ( TypeDecl * type : func->get_forall() ) {
    563                         std::list< DeclarationWithType * > toBeDone, nextRound;
    564                         toBeDone.splice( toBeDone.end(), type->get_assertions() );
    565                         while ( ! toBeDone.empty() ) {
    566                                 for ( DeclarationWithType * assertion : toBeDone ) {
    567                                         if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
    568                                                 // expand trait instance into all of its members
    569                                                 for ( Declaration * member : traitInst->get_members() ) {
    570                                                         DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
    571                                                         nextRound.push_back( dwt->clone() );
    572                                                 }
    573                                                 delete traitInst;
    574                                         } else {
    575                                                 // pass assertion through
    576                                                 FixFunction fixer;
    577                                                 assertion = assertion->acceptMutator( fixer );
    578                                                 if ( fixer.get_isVoid() ) {
    579                                                         throw SemanticError( "invalid type void in assertion of function ", func );
    580                                                 }
    581                                                 type->get_assertions().push_back( assertion );
    582                                         } // if
    583                                 } // for
    584                                 toBeDone.clear();
    585                                 toBeDone.splice( toBeDone.end(), nextRound );
    586                         } // while
     603                        std::list< DeclarationWithType * > asserts;
     604                        asserts.splice( asserts.end(), type->assertions );
     605                        // expand trait instances into their members
     606                        for ( DeclarationWithType * assertion : asserts ) {
     607                                if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     608                                        // expand trait instance into all of its members
     609                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     610                                        delete traitInst;
     611                                } else {
     612                                        // pass other assertions through
     613                                        type->assertions.push_back( assertion );
     614                                } // if
     615                        } // for
     616                        // apply FixFunction to every assertion to check for invalid void type
     617                        for ( DeclarationWithType *& assertion : type->assertions ) {
     618                                FixFunction fixer;
     619                                assertion = assertion->acceptMutator( fixer );
     620                                if ( fixer.get_isVoid() ) {
     621                                        throw SemanticError( "invalid type void in assertion of function ", func );
     622                                } // if
     623                        } // for
     624                        // normalizeAssertions( type->assertions );
    587625                } // for
    588626        }
     
    752790                CompoundStmt *ret = Mutator::mutate( compoundStmt );
    753791                scopeLevel -= 1;
    754                 std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
    755                 while ( i != compoundStmt->get_kids().end() ) {
    756                         std::list< Statement * >::iterator next = i+1;
    757                         if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) {
     792                // remove and delete decl stmts
     793                filter( compoundStmt->kids, [](Statement * stmt) {
     794                        if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    758795                                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    759                                         delete *i;
    760                                         compoundStmt->get_kids().erase( i );
     796                                        return true;
    761797                                } // if
    762798                        } // if
    763                         i = next;
    764                 } // while
     799                        return false;
     800                }, true);
    765801                typedefNames.endScope();
    766802                return ret;
     
    771807        template<typename AggDecl>
    772808        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
    773                 std::list<Declaration *>::iterator it = aggDecl->get_members().begin();
    774                 for ( ; it != aggDecl->get_members().end(); ) {
    775                         std::list< Declaration * >::iterator next = it+1;
    776                         if ( dynamic_cast< TypedefDecl * >( *it ) ) {
    777                                 delete *it;
    778                                 aggDecl->get_members().erase( it );
    779                         } // if
    780                         it = next;
    781                 }
     809                filter( aggDecl->members, isTypedef, true );
    782810                return aggDecl;
    783811        }
     
    957985        }
    958986
     987        struct LabelFinder {
     988                std::set< Label > & labels;
     989                LabelFinder( std::set< Label > & labels ) : labels( labels ) {}
     990                void previsit( Statement * stmt ) {
     991                        for ( Label & l : stmt->labels ) {
     992                                labels.insert( l );
     993                        }
     994                }
     995        };
     996
     997        void LabelAddressFixer::premutate( FunctionDecl * funcDecl ) {
     998                GuardValue( labels );
     999                PassVisitor<LabelFinder> finder( labels );
     1000                funcDecl->accept( finder );
     1001        }
     1002
     1003        Expression * LabelAddressFixer::postmutate( AddressExpr * addrExpr ) {
     1004                // convert &&label into label address
     1005                if ( AddressExpr * inner = dynamic_cast< AddressExpr * >( addrExpr->arg ) ) {
     1006                        if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( inner->arg ) ) {
     1007                                if ( labels.count( nameExpr->name ) ) {
     1008                                        Label name = nameExpr->name;
     1009                                        delete addrExpr;
     1010                                        return new LabelAddressExpr( name );
     1011                                }
     1012                        }
     1013                }
     1014                return addrExpr;
     1015        }
     1016
    9591017        void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
    9601018                if ( ! dereferenceOperator ) {
  • src/SynTree/AddressExpr.cc

    r800d275 r235b41f  
    7070}
    7171
     72LabelAddressExpr::LabelAddressExpr( const Label &arg ) : arg( arg ) {
     73        // label address always has type void *
     74        result = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
     75}
     76LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}
     77LabelAddressExpr::~LabelAddressExpr() {}
     78
     79void LabelAddressExpr::print( std::ostream & os, int indent ) const {
     80        os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;
     81}
     82
    7283// Local Variables: //
    7384// tab-width: 4 //
  • src/SynTree/Declaration.h

    r800d275 r235b41f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Aug 14 10:15:00 2017
    13 // Update Count     : 128
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Sep  3 19:24:06 2017
     13// Update Count     : 131
    1414//
    1515
     
    8282        int scopeLevel = 0;
    8383
    84         ConstantExpr *asmName;
     84        Expression *asmName;
    8585        std::list< Attribute * > attributes;
    8686
     
    9797        DeclarationWithType * set_scopeLevel( int newValue ) { scopeLevel = newValue; return this; }
    9898
    99         ConstantExpr *get_asmName() const { return asmName; }
    100         DeclarationWithType * set_asmName( ConstantExpr *newValue ) { asmName = newValue; return this; }
     99        Expression *get_asmName() const { return asmName; }
     100        DeclarationWithType * set_asmName( Expression *newValue ) { asmName = newValue; return this; }
    101101
    102102        std::list< Attribute * >& get_attributes() { return attributes; }
  • src/SynTree/Expression.h

    r800d275 r235b41f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug  8 11:54:00 2017
    13 // Update Count     : 44
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Sep  3 19:23:46 2017
     13// Update Count     : 48
    1414//
     15
    1516#pragma once
    1617
     
    2425#include "Constant.h"             // for Constant
    2526#include "Initializer.h"          // for Designation (ptr only), Initializer
     27#include "Label.h"                // for Label
    2628#include "Mutator.h"              // for Mutator
    2729#include "SynTree.h"              // for UniqueId
     
    173175};
    174176
    175 // xxx - this doesn't appear to actually be hooked in anywhere. We should use this instead of the "&&"" UntypedExpr hack
     177// GCC &&label
     178// https://gcc.gnu.org/onlinedocs/gcc-3.4.2/gcc/Labels-as-Values.html
    176179class LabelAddressExpr : public Expression {
    177180  public:
    178         Expression * arg;
    179 
    180         LabelAddressExpr( Expression * arg );
     181        Label arg;
     182
     183        LabelAddressExpr( const Label &arg );
    181184        LabelAddressExpr( const LabelAddressExpr & other );
    182185        virtual ~LabelAddressExpr();
    183 
    184         Expression * get_arg() const { return arg; }
    185         void set_arg(Expression * newValue ) { arg = newValue; }
    186186
    187187        virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
     
    540540  public:
    541541        Expression * inout;
    542         ConstantExpr * constraint;
     542        Expression * constraint;
    543543        Expression * operand;
    544544
    545         AsmExpr( Expression * inout, ConstantExpr * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
     545        AsmExpr( Expression * inout, Expression * constraint, Expression * operand ) : inout( inout ), constraint( constraint ), operand( operand ) {}
    546546        AsmExpr( const AsmExpr & other );
    547547        virtual ~AsmExpr() { delete inout; delete constraint; delete operand; };
     
    550550        void set_inout( Expression * newValue ) { inout = newValue; }
    551551
    552         ConstantExpr * get_constraint() const { return constraint; }
    553         void set_constraint( ConstantExpr * newValue ) { constraint = newValue; }
     552        Expression * get_constraint() const { return constraint; }
     553        void set_constraint( Expression * newValue ) { constraint = newValue; }
    554554
    555555        Expression * get_operand() const { return operand; }
  • src/SynTree/Mutator.cc

    r800d275 r235b41f  
    246246        labelAddressExpr->set_env( maybeMutate( labelAddressExpr->get_env(), *this ) );
    247247        labelAddressExpr->set_result( maybeMutate( labelAddressExpr->get_result(), *this ) );
    248         labelAddressExpr->set_arg( maybeMutate( labelAddressExpr->get_arg(), *this ) );
    249248        return labelAddressExpr;
    250249}
     
    538537Type * Mutator::mutate( TraitInstType *aggregateUseType ) {
    539538        handleReferenceToType( aggregateUseType );
    540         mutateAll( aggregateUseType->get_members(), *this );
    541539        return aggregateUseType;
    542540}
  • src/SynTree/ReferenceToType.cc

    r800d275 r235b41f  
    132132std::string TraitInstType::typeString() const { return "trait"; }
    133133
    134 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
    135         cloneAll( other.members, members );
     134TraitInstType::TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes ) : Parent( tq, baseTrait->name, attributes ), baseTrait( baseTrait ) {}
     135
     136TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ), baseTrait( other.baseTrait ) {
    136137}
    137138
    138139TraitInstType::~TraitInstType() {
    139         deleteAll( members );
    140140}
    141141
  • src/SynTree/Statement.cc

    r800d275 r235b41f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 16:17:20 2017
    13 // Update Count     : 67
     12// Last Modified On : Sun Sep  3 20:46:44 2017
     13// Update Count     : 68
    1414//
    1515
     
    5252
    5353
    54 AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, ConstantExpr *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
     54AsmStmt::AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels ) : Statement( labels ), voltile( voltile ), instruction( instruction ), output( output ), input( input ), clobber( clobber ), gotolabels( gotolabels ) {}
    5555
    5656AsmStmt::AsmStmt( const AsmStmt & other ) : Statement( other ), voltile( other.voltile ), instruction( maybeClone( other.instruction ) ), gotolabels( other.gotolabels ) {
     
    8989
    9090BranchStmt::BranchStmt( std::list<Label> labels, Label target, Type type ) throw ( SemanticError ) :
    91         Statement( labels ), originalTarget( target ), target( target ), computedTarget( NULL ), type( type ) {
     91        Statement( labels ), originalTarget( target ), target( target ), computedTarget( nullptr ), type( type ) {
    9292        //actually this is a syntactic error signaled by the parser
    93         if ( type == BranchStmt::Goto && target.empty() )
     93        if ( type == BranchStmt::Goto && target.empty() ) {
    9494                throw SemanticError("goto without target");
     95        }
    9596}
    9697
    9798BranchStmt::BranchStmt( std::list<Label> labels, Expression *computedTarget, Type type ) throw ( SemanticError ) :
    9899        Statement( labels ), computedTarget( computedTarget ), type( type ) {
    99         if ( type != BranchStmt::Goto || computedTarget == 0 )
     100        if ( type != BranchStmt::Goto || computedTarget == nullptr ) {
    100101                throw SemanticError("Computed target not valid in branch statement");
     102        }
    101103}
    102104
    103105void BranchStmt::print( std::ostream &os, int indent ) const {
    104106        os << string( indent, ' ' ) << "Branch (" << brType[type] << ")" << endl ;
     107        if ( target != "" ) os << string( indent+2, ' ' ) << "with target: " << target << endl;
     108        if ( originalTarget != "" ) os << string( indent+2, ' ' ) << "with original target: " << originalTarget << endl;
     109        if ( computedTarget != nullptr ) os << string( indent+2, ' ' ) << "with computed target: " << computedTarget << endl;
    105110}
    106111
  • src/SynTree/Statement.h

    r800d275 r235b41f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 15:37:53 2017
    13 // Update Count     : 72
     12// Last Modified On : Sun Sep  3 20:46:46 2017
     13// Update Count     : 77
    1414//
    1515
     
    9898  public:
    9999        bool voltile;
    100         ConstantExpr *instruction;
     100        Expression *instruction;
    101101        std::list<Expression *> output, input;
    102102        std::list<ConstantExpr *> clobber;
    103103        std::list<Label> gotolabels;
    104104
    105         AsmStmt( std::list<Label> labels, bool voltile, ConstantExpr *instruction, std::list<Expression *> input, std::list<Expression *> output, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
     105        AsmStmt( std::list<Label> labels, bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
    106106        AsmStmt( const AsmStmt &other );
    107107        virtual ~AsmStmt();
     
    109109        bool get_voltile() { return voltile; }
    110110        void set_voltile( bool newValue ) { voltile = newValue; }
    111         ConstantExpr *get_instruction() { return instruction; }
    112         void set_instruction( ConstantExpr *newValue ) { instruction = newValue; }
    113         std::list<Expression *> &get_output() { return output; }
    114         void set_output( const std::list<Expression *> &newValue ) { output = newValue; }
    115         std::list<Expression *> &get_input() { return input; }
     111        Expression * get_instruction() { return instruction; }
     112        void set_instruction( Expression * newValue ) { instruction = newValue; }
     113        std::list<Expression *> & get_output() { return output; }
     114        void set_output( const std::list<Expression *> & newValue ) { output = newValue; }
     115        std::list<Expression *> & get_input() { return input; }
    116116        void set_input( const std::list<Expression *> &newValue ) { input = newValue; }
    117         std::list<ConstantExpr *> &get_clobber() { return clobber; }
     117        std::list<ConstantExpr *> & get_clobber() { return clobber; }
    118118        void set_clobber( const std::list<ConstantExpr *> &newValue ) { clobber = newValue; }
    119         std::list<Label> &get_gotolabels() { return gotolabels; }
     119        std::list<Label> & get_gotolabels() { return gotolabels; }
    120120        void set_gotolabels( const std::list<Label> &newValue ) { gotolabels = newValue; }
    121121
    122         virtual AsmStmt *clone() const { return new AsmStmt( *this ); }
    123         virtual void accept( Visitor &v ) { v.visit( this ); }
    124         virtual Statement *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    125         virtual void print( std::ostream &os, int indent = 0 ) const;
     122        virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
     123        virtual void accept( Visitor & v ) { v.visit( this ); }
     124        virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     125        virtual void print( std::ostream & os, int indent = 0 ) const;
    126126};
    127127
  • src/SynTree/Type.h

    r800d275 r235b41f  
    471471        typedef ReferenceToType Parent;
    472472  public:
    473         // this member is filled in by the validate pass, which instantiates the members of the correponding
    474         // aggregate with the actual type parameters specified for this use of the context
    475         std::list< Declaration* > members;
    476 
    477         TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >()  ) : Parent( tq, name, attributes ) {}
     473        // this decl is not "owned" by the trait inst; it is merely a pointer to elsewhere in the tree,
     474        // where the trait used in this type is actually defined
     475        TraitDecl * baseTrait = nullptr;
     476
     477        TraitInstType( const Type::Qualifiers & tq, const std::string & name, const std::list< Attribute * > & attributes = std::list< Attribute * >() ) : Parent( tq, name, attributes ) {}
     478        TraitInstType( const Type::Qualifiers & tq, TraitDecl * baseTrait, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    478479        TraitInstType( const TraitInstType & other );
    479480        ~TraitInstType();
    480 
    481         std::list< Declaration* >& get_members() { return members; }
    482481
    483482        virtual bool isComplete() const;
  • src/SynTree/TypeSubstitution.h

    r800d275 r235b41f  
    177177void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
    178178        TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
    179         for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) {
     179        for ( auto i = memberBegin; i != memberEnd; ++i ) {
    180180                sub.apply( *i );
    181181                *out++ = *i;
  • src/SynTree/Visitor.cc

    r800d275 r235b41f  
    205205void Visitor::visit( LabelAddressExpr *labAddressExpr ) {
    206206        maybeAccept( labAddressExpr->get_result(), *this );
    207         maybeAccept( labAddressExpr->get_arg(), *this );
    208207}
    209208
     
    429428void Visitor::visit( TraitInstType *aggregateUseType ) {
    430429        handleReferenceToType( static_cast< ReferenceToType * >( aggregateUseType ) );
    431         acceptAll( aggregateUseType->get_members(), *this );
    432430}
    433431
  • src/libcfa/concurrency/coroutine

    r800d275 r235b41f  
    1 //                              - *- Mode: CFA - *-
    21//
    32// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1110// Created On       : Mon Nov 28 12:27:26 2016
    1211// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Sat Jul 22 09:57:17 2017
    14 // Update Count     : 2
     12// Last Modified On : Wed Aug 30 07:58:29 2017
     13// Update Count     : 3
    1514//
    1615
  • src/libcfa/gmp

    r800d275 r235b41f  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 24 09:24:51 2017
    13 // Update Count     : 16
     12// Last Modified On : Mon Sep  4 09:54:33 2017
     13// Update Count     : 20
    1414//
    1515
     
    3232static inline void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
    3333static inline void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
     34
     35// literal
     36static inline Int ?`mp( signed long int init ) { return (Int){ init }; }
     37static inline Int ?`mp( unsigned long int init ) { return (Int){ init }; }
     38static inline Int ?`mp( const char * init ) { return (Int){ init }; }
    3439
    3540// assignment
  • src/prelude/prelude.cf

    r800d275 r235b41f  
    1 //                               -*- Mode: C -*-
    21//
    32// Copyright (C) Glen Ditchfield 1994, 1999
     
    87// Created On       : Sat Nov 29 07:23:41 2014
    98// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Tue Jul  5 18:04:40 2016
    11 // Update Count     : 92
     9// Last Modified On : Wed Aug 30 07:56:07 2017
     10// Update Count     : 93
    1211//
    1312
     
    1514
    1615// Section numbers from: http://plg.uwaterloo.ca/~cforall/refrat.pdf
     16
     17// ------------------------------------------------------------
     18//
     19// Section 6.7.11 Trait Declarations
     20// Note: the sized trait is used in declarations later in this
     21// file, so it must be out of order.
     22//
     23// ------------------------------------------------------------
     24
     25trait sized(dtype T) {};
    1726
    1827// ------------------------------------------------------------
  • src/tests/.expect/64/gmp.txt

    r800d275 r235b41f  
    55y:97
    66y:12345678901234567890123456789
     7y:200
     8y:-400
     9y:24691357802469135780246913578
    710y:3
    811y:-3
  • src/tests/.expect/dtor-early-exit-ERR1.txt

    r800d275 r235b41f  
    11dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
     2  with target: L1
     3  with original target: L1
    24
  • src/tests/.expect/dtor-early-exit-ERR2.txt

    r800d275 r235b41f  
    11dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
     2  with target: L2
     3  with original target: L2
    24
  • src/tests/.expect/ifcond.txt

    r800d275 r235b41f  
    11x != 0 correct
    2 x != 0 && y == 0 incorrect
     2x != 0 && y != 0 correct
    33x == y correct
  • src/tests/div.c

    r800d275 r235b41f  
    1 //                               -*- Mode: C -*-
    21//
    32// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1110// Created On       : Tue Aug  8 16:28:43 2017
    1211// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Aug  9 17:09:40 2017
    14 // Update Count     : 16
     12// Last Modified On : Wed Aug 30 07:56:28 2017
     13// Update Count     : 17
    1514//
    1615
  • src/tests/dtor-early-exit.c

    r800d275 r235b41f  
    220220}
    221221
     222// TODO: implement __label__ and uncomment these lines
     223void computedGoto() {
     224  // __label__ bar;
     225  void *ptr;
     226  ptr = &&foo;
     227  goto *ptr;
     228  assert(false);
     229foo: ;
     230//   void f() {
     231//     ptr = &&bar;
     232//     goto *ptr;
     233//     assert(false);
     234//   }
     235//   f();
     236//   assert(false);
     237// bar: ;
     238}
     239
    222240int main() {
    223241        sepDisable(sout);
     
    229247        sout | endl;
    230248        h();
     249
     250        computedGoto();
    231251}
    232252
  • src/tests/gmp.c

    r800d275 r235b41f  
    1010// Created On       : Tue Apr 19 08:55:51 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 25 12:50:01 2017
    13 // Update Count     : 544
     12// Last Modified On : Mon Sep  4 09:51:18 2017
     13// Update Count     : 550
    1414//
    1515
     
    2929        sout | "y:" | y | endl;
    3030        y = "12345678901234567890123456789";
     31        sout | "y:" | y | endl;
     32        y = 100`mp + 100`mp;
     33        sout | "y:" | y | endl;
     34        y = -200u`mp + -200u`mp;
     35        sout | "y:" | y | endl;
     36        y = "12345678901234567890123456789"`mp + "12345678901234567890123456789"`mp;
    3137        sout | "y:" | y | endl;
    3238        y = si;
  • src/tests/ifcond.c

    r800d275 r235b41f  
    1 //                               -*- Mode: C -*-
    2 //
     1//
    32// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
    43//
    54// The contents of this file are covered under the licence agreement in the
    65// file "LICENCE" distributed with Cforall.
    7 // 
    8 // ifcond.c -- 
    9 // 
     6//
     7// ifcond.c --
     8//
    109// Author           : Peter A. Buhr
    1110// Created On       : Sat Aug 26 10:13:11 2017
    12 // Last Modified By : Peter A. Buhr
    13 // Last Modified On : Tue Aug 29 08:25:02 2017
    14 // Update Count     : 12
    15 // 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri Sep 01 15:22:19 2017
     13// Update Count     : 14
     14//
    1615
    17 #include<fstream>
     16#include <fstream>
    1817
    1918int f( int r ) { return r; }
     
    2827        } // if
    2928
    30         if ( int x = 4, y = 0 ) {                                                       // FIXME && distribution
     29        if ( int x = 4, y = 0 ) {
     30                sout | "x != 0 && y != 0 incorrect" | endl;
     31        } else if ( int x = 4, y = 1 ) {
    3132                sout | "x != 0 && y != 0 correct" | endl;
    32     } else {
    33                 sout | "x != 0 && y == 0 incorrect" | endl;
     33        } else {
     34                sout | "x == 0 || y == 0 incorrect" | endl;
    3435        } // if
    3536
  • src/tests/stdincludes.c

    r800d275 r235b41f  
    1 //                              -*- Mode: C++ -*-
    21//
    32// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
     
    1110// Created On       : Tue Aug 29 08:26:14 2017
    1211// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Tue Aug 29 08:52:11 2017
    14 // Update Count     : 4
     12// Last Modified On : Wed Aug 30 07:56:39 2017
     13// Update Count     : 5
    1514//
    1615
  • tools/prettyprinter/lex.ll

    r800d275 r235b41f  
    77 * lex.ll --
    88 *
    9  * Author           : Rodolfo Gabriel Esteves
     9 * Author           : Peter A. Buhr
    1010 * Created On       : Sat Dec 15 11:45:59 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Fri Jul 21 23:06:16 2017
    13  * Update Count     : 254
     12 * Last Modified On : Tue Aug 29 17:33:36 2017
     13 * Update Count     : 268
    1414 */
    1515
    1616%option stack
    1717%option yylineno
     18%option nounput
    1819
    1920%{
     
    3031string comment_str;
    3132string code_str;
     33
     34// Stop warning due to incorrectly generated flex code.
     35#pragma GCC diagnostic ignored "-Wsign-compare"
    3236%}
    3337
     
    4448/* ---------------------------- Token Section ---------------------------- */
    4549%%
    46 <INITIAL,C_CODE>"/*"    {                               /* C style comments */
    47                         #if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
    48                             cerr << "\"/*\" : " << yytext << endl;
    49                         #endif
    50                             if ( YYSTATE == C_CODE ) code_str += yytext;
    51                             else comment_str += yytext;
    52                             yy_push_state(C_COMMENT);
    53                         }
    54 <C_COMMENT>(.|"\n")     {                               /* C style comments */
    55                         #if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
    56                             cerr << "<C_COMMENT>(.|\\n) : " << yytext << endl;
    57                         #endif
    58                             if ( yy_top_state() == C_CODE ) code_str += yytext;
    59                             else comment_str += yytext;
    60                         }
    61 <C_COMMENT>"*/"         {                               /* C style comments */
    62                         #if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
    63                             cerr << "<C_COMMENT>\"*/\" : " << yytext << endl;
    64                         #endif
    65                             if ( yy_top_state() == C_CODE ) code_str += yytext;
    66                             else {
    67                                 comment_str += yytext;
    68                                 //cerr << "C COMMENT : " << endl << comment_str << endl;
    69                                 ws_list.push_back( comment_str );
    70                                 comment_str = "";
    71                             }
    72                             yy_pop_state();
    73                         }
    74 <INITIAL,C_CODE>"//"[^\n]*"\n" {                        /* C++ style comments */
    75                         #if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
    76                             cerr << "\"//\"[^\\n]*\"\n\" : " << yytext << endl;
    77                         #endif
    78                             if ( YYSTATE == C_CODE ) code_str += yytext;
    79                             else {
    80                                 comment_str += yytext;
    81                                 //cerr << "C++ COMMENT : " << endl << comment_str << endl;
    82                                 ws_list.push_back( comment_str );
    83                                 comment_str = "";
    84                             }
    85                         }
     50<INITIAL,C_CODE>"/*" {                                                                  // C style comments */
     51#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
     52    cerr << "\"/*\" : " << yytext << endl;
     53#endif
     54    if ( YYSTATE == C_CODE ) code_str += yytext;
     55    else comment_str += yytext;
     56    yy_push_state(C_COMMENT);
     57}
     58<C_COMMENT>(.|"\n")     {                                                                       // C style comments
     59#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
     60    cerr << "<C_COMMENT>(.|\\n) : " << yytext << endl;
     61#endif
     62    if ( yy_top_state() == C_CODE ) code_str += yytext;
     63    else comment_str += yytext;
     64}
     65<C_COMMENT>"*/" {                                                                               // C style comments
     66#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
     67        cerr << "<C_COMMENT>\"*/\" : " << yytext << endl;
     68#endif
     69        if ( yy_top_state() == C_CODE ) code_str += yytext;
     70        else {
     71                comment_str += yytext;
     72                //cerr << "C COMMENT : " << endl << comment_str << endl;
     73                ws_list.push_back( comment_str );
     74                comment_str = "";
     75        }
     76        yy_pop_state();
     77}
    8678
    87 ";"                     { RETURN_TOKEN( ';' ) }
    88 ":"                     { RETURN_TOKEN( ':' ) }
    89 "|"                     { RETURN_TOKEN( '|' ) }
    90 ","                     { RETURN_TOKEN( ',' ) }
    91 "<"                     { RETURN_TOKEN( '<' ) }
    92 ">"                     { RETURN_TOKEN( '>' ) }
     79<INITIAL,C_CODE>"//"[^\n]*"\n" {                                                // C++ style comments
     80#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
     81        cerr << "\"//\"[^\\n]*\"\n\" : " << yytext << endl;
     82#endif
     83        if ( YYSTATE == C_CODE ) code_str += yytext;
     84        else {
     85                comment_str += yytext;
     86                //cerr << "C++ COMMENT : " << endl << comment_str << endl;
     87                ws_list.push_back( comment_str );
     88                comment_str = "";
     89        }
     90}
    9391
    94 [[:space:]]+            {                               /* [ \t\n]+ */
    95                             ws_list.push_back( yytext );
    96                             //cerr << "WS : " << "\"" << yytext << "\"" << endl;
    97                         }
     92";"                             { RETURN_TOKEN( ';' ) }
     93":"                             { RETURN_TOKEN( ':' ) }
     94"|"                             { RETURN_TOKEN( '|' ) }
     95","                             { RETURN_TOKEN( ',' ) }
     96"<"                             { RETURN_TOKEN( '<' ) }
     97">"                             { RETURN_TOKEN( '>' ) }
    9898
    99 <INITIAL>"{"            { RETURN_TOKEN( '{' ) }
    100 <INITIAL>"}"            { RETURN_TOKEN( '}' ) }
    101 <C_CODE>"{"             {
    102                         #if defined(DEBUG_ALL) | defined(DEBUG_C)
    103                             cerr << "<C_CODE>. : " << yytext << endl;
    104                         #endif
    105                             code_str += yytext;
    106                             RETURN_TOKEN( '{' )
    107                         }
    108 <C_CODE>"}"             {
    109                         #if defined(DEBUG_ALL) | defined(DEBUG_C)
    110                             cerr << "<C_CODE>. : " << yytext << endl;
    111                         #endif
    112                             code_str += yytext;
    113                             RETURN_TOKEN( '}' )
    114                         }
     99[[:space:]]+ {                                                                                  // [ \t\n]+
     100        ws_list.push_back( yytext );
     101        //cerr << "WS : " << "\"" << yytext << "\"" << endl;
     102}
     103
     104<INITIAL>"{"    { RETURN_TOKEN( '{' ) }
     105<INITIAL>"}"    { RETURN_TOKEN( '}' ) }
     106<C_CODE>"{"     {
     107#if defined(DEBUG_ALL) | defined(DEBUG_C)
     108        cerr << "<C_CODE>. : " << yytext << endl;
     109#endif
     110        code_str += yytext;
     111        RETURN_TOKEN( '{' )
     112}
     113<C_CODE>"}"     {
     114#if defined(DEBUG_ALL) | defined(DEBUG_C)
     115        cerr << "<C_CODE>. : " << yytext << endl;
     116#endif
     117        code_str += yytext;
     118        RETURN_TOKEN( '}' )
     119}
    115120
    116121"%%"                    { RETURN_TOKEN( MARK ) }
    117122"%{"                    { RETURN_TOKEN( LCURL ) }
    118 <C_CODE>"%}"            { RETURN_TOKEN( RCURL ) }
     123<C_CODE>"%}"    { RETURN_TOKEN( RCURL ) }
    119124
    120 ^"%union"               { RETURN_TOKEN( UNION ) }
    121 ^"%start"               { RETURN_TOKEN( START ) }
    122 ^"%token"               { RETURN_TOKEN( TOKEN ) }
    123 ^"%type"                { RETURN_TOKEN( TYPE ) }
    124 ^"%left"                { RETURN_TOKEN( LEFT ) }
    125 ^"%right"               { RETURN_TOKEN( RIGHT ) }
    126 ^"%nonassoc"            { RETURN_TOKEN( NONASSOC ) }
    127 ^"%pure_parser"         { RETURN_TOKEN( PURE_PARSER ) }
    128 ^"%semantic_parser"     { RETURN_TOKEN( SEMANTIC_PARSER ) }
    129 ^"%expect"              { RETURN_TOKEN( EXPECT ) }
     125^"%union"       { RETURN_TOKEN( UNION ) }
     126^"%start"       { RETURN_TOKEN( START ) }
     127^"%token"       { RETURN_TOKEN( TOKEN ) }
     128^"%type"            { RETURN_TOKEN( TYPE ) }
     129^"%left"            { RETURN_TOKEN( LEFT ) }
     130^"%right"           { RETURN_TOKEN( RIGHT ) }
     131^"%nonassoc"    { RETURN_TOKEN( NONASSOC ) }
     132^"%precedence"  { RETURN_TOKEN( PRECEDENCE ) }
     133^"%pure_parser" { RETURN_TOKEN( PURE_PARSER ) }
     134^"%semantic_parser"     { RETURN_TOKEN( SEMANTIC_PARSER ) }
     135^"%expect"      { RETURN_TOKEN( EXPECT ) }
    130136^"%thong"               { RETURN_TOKEN( THONG ) }
    131137
    132138"%prec"                 { RETURN_TOKEN( PREC ) }
    133139
    134 {integer}               { RETURN_TOKEN( INTEGER ); }
    135 [']{c_char}[']          { RETURN_TOKEN( CHARACTER ); }
    136 {identifier}            { RETURN_TOKEN( IDENTIFIER ); }
     140{integer}           { RETURN_TOKEN( INTEGER ); }
     141[']{c_char}[']  { RETURN_TOKEN( CHARACTER ); }
     142{identifier}    { RETURN_TOKEN( IDENTIFIER ); }
    137143
    138 <C_CODE>["]{s_char}*["] {                               /* hide braces "{}" in strings */
    139                         #if defined(DEBUG_ALL) | defined(DEBUG_C)
    140                             cerr << "<C_CODE>. : " << yytext << endl;
    141                         #endif
    142                             code_str += yytext;
    143                         }
     144<C_CODE>["]{s_char}*["] {                                                               // hide braces "{}" in strings
     145#if defined(DEBUG_ALL) | defined(DEBUG_C)
     146        cerr << "<C_CODE>. : " << yytext << endl;
     147#endif
     148        code_str += yytext;
     149}
    144150
    145 <C_CODE>(.|\n)          {                               /* must be last rule of C_CODE */
    146                         #if defined(DEBUG_ALL) | defined(DEBUG_C)
    147                             cerr << "<C_CODE>. : " << yytext << endl;
    148                         #endif
    149                             code_str += yytext;
    150                         }
     151<C_CODE>(.|\n) {                                                                                // must be last rule of C_CODE
     152#if defined(DEBUG_ALL) | defined(DEBUG_C)
     153        cerr << "<C_CODE>. : " << yytext << endl;
     154#endif
     155        code_str += yytext;
     156}
    151157
    152 .                       { printf("UNKNOWN CHARACTER:%s\n", yytext); } /* unknown characters */
     158                                /* unknown characters */
     159.                               { printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno); }
    153160%%
    154161void lexC(void) {
  • tools/prettyprinter/parser.hh

    r800d275 r235b41f  
    5959    RIGHT = 269,
    6060    NONASSOC = 270,
    61     TYPE = 271,
    62     PURE_PARSER = 272,
    63     SEMANTIC_PARSER = 273,
    64     EXPECT = 274,
    65     THONG = 275,
    66     PREC = 276,
    67     END_TERMINALS = 277,
    68     _SECTIONS = 278,
    69     _DEFSECTION_OPT = 279,
    70     _LITERALBLOCK = 280,
    71     _DECLARATION = 281,
    72     _TAG_OPT = 282,
    73     _NAMENOLIST = 283,
    74     _NAMENO = 284,
    75     _NAMELIST = 285,
    76     _RULESECTION = 286,
    77     _RULE = 287,
    78     _LHS = 288,
    79     _RHS = 289,
    80     _PREC = 290,
    81     _ACTION = 291,
    82     _USERSECTION_OPT = 292
     61    PRECEDENCE = 271,
     62    TYPE = 272,
     63    PURE_PARSER = 273,
     64    SEMANTIC_PARSER = 274,
     65    EXPECT = 275,
     66    THONG = 276,
     67    PREC = 277,
     68    END_TERMINALS = 278,
     69    _SECTIONS = 279,
     70    _DEFSECTION_OPT = 280,
     71    _LITERALBLOCK = 281,
     72    _DECLARATION = 282,
     73    _TAG_OPT = 283,
     74    _NAMENOLIST = 284,
     75    _NAMENO = 285,
     76    _NAMELIST = 286,
     77    _RULESECTION = 287,
     78    _RULE = 288,
     79    _LHS = 289,
     80    _RHS = 290,
     81    _PREC = 291,
     82    _ACTION = 292,
     83    _USERSECTION_OPT = 293
    8384  };
    8485#endif
     
    9798#define RIGHT 269
    9899#define NONASSOC 270
    99 #define TYPE 271
    100 #define PURE_PARSER 272
    101 #define SEMANTIC_PARSER 273
    102 #define EXPECT 274
    103 #define THONG 275
    104 #define PREC 276
    105 #define END_TERMINALS 277
    106 #define _SECTIONS 278
    107 #define _DEFSECTION_OPT 279
    108 #define _LITERALBLOCK 280
    109 #define _DECLARATION 281
    110 #define _TAG_OPT 282
    111 #define _NAMENOLIST 283
    112 #define _NAMENO 284
    113 #define _NAMELIST 285
    114 #define _RULESECTION 286
    115 #define _RULE 287
    116 #define _LHS 288
    117 #define _RHS 289
    118 #define _PREC 290
    119 #define _ACTION 291
    120 #define _USERSECTION_OPT 292
     100#define PRECEDENCE 271
     101#define TYPE 272
     102#define PURE_PARSER 273
     103#define SEMANTIC_PARSER 274
     104#define EXPECT 275
     105#define THONG 276
     106#define PREC 277
     107#define END_TERMINALS 278
     108#define _SECTIONS 279
     109#define _DEFSECTION_OPT 280
     110#define _LITERALBLOCK 281
     111#define _DECLARATION 282
     112#define _TAG_OPT 283
     113#define _NAMENOLIST 284
     114#define _NAMENO 285
     115#define _NAMELIST 286
     116#define _RULESECTION 287
     117#define _RULE 288
     118#define _LHS 289
     119#define _RHS 290
     120#define _PREC 291
     121#define _ACTION 292
     122#define _USERSECTION_OPT 293
    121123
    122124/* Value type.  */
     
    129131        Token *tokenp;
    130132
    131 #line 132 "parser.hh" /* yacc.c:1909  */
     133#line 134 "parser.hh" /* yacc.c:1909  */
    132134};
    133135
  • tools/prettyprinter/parser.yy

    r800d275 r235b41f  
    1010// Created On       : Sat Dec 15 13:44:21 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 29 09:26:47 2017
    13 // Update Count     : 1045
     12// Last Modified On : Tue Aug 29 16:34:10 2017
     13// Update Count     : 1047
    1414//
    1515
     
    6767%token<tokenp>  RIGHT                                                                   // %right
    6868%token<tokenp>  NONASSOC                                                                // %nonassoc
     69%token<tokenp>  PRECEDENCE                                                              // %precedence
    6970%token<tokenp>  TYPE                                                                    // %type
    7071%token<tokenp>  PURE_PARSER                                                             // %pure_parser
     
    259260        | RIGHT
    260261        | NONASSOC
     262        | PRECEDENCE
    261263        ;
    262264
Note: See TracChangeset for help on using the changeset viewer.