Changeset cc7bbe6 for src


Ignore:
Timestamp:
Feb 23, 2022, 11:24:34 AM (4 years ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
Children:
08ed947
Parents:
f5a51db (diff), 3a038fa (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

Location:
src
Files:
4 added
2 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.hpp

    rf5a51db rcc7bbe6  
    2020class Declaration;
    2121namespace ast {
    22         struct TranslationUnit;
     22        class TranslationUnit;
    2323};
    2424
  • src/AST/Decl.cpp

    rf5a51db rcc7bbe6  
    3939        if ( uniqueId ) return;  // ensure only set once
    4040        uniqueId = ++lastUniqueId;
    41         idMap[ uniqueId ] = this;
     41        // The extra readonly pointer is causing some reference counting issues.
     42        // idMap[ uniqueId ] = this;
    4243}
    4344
    4445readonly<Decl> Decl::fromId( UniqueId id ) {
     46        // Right now this map is always empty, so don't use it.
     47        assert( false );
    4548        IdMapType::const_iterator i = idMap.find( id );
    4649        if ( i != idMap.end() ) return i->second;
  • src/AST/Fwd.hpp

    rf5a51db rcc7bbe6  
    140140typedef unsigned int UniqueId;
    141141
    142 struct TranslationUnit;
     142class TranslationUnit;
    143143// TODO: Get from the TranslationUnit:
    144144extern ptr<Type> sizeType;
  • src/AST/Pass.hpp

    rf5a51db rcc7bbe6  
    239239private:
    240240
    241         // Regular nodes
     241        __pass::result1<ast::Stmt> call_accept( const ast::Stmt * );
     242        __pass::result1<ast::Expr> call_accept( const ast::Expr * );
     243
     244        /// This has a `type` member that is the return type for the
     245        /// generic call_accept if the generic call_accept is defined.
    242246        template< typename node_t >
    243         struct result1 {
    244                 bool differs;
    245                 const node_t * value;
    246 
    247                 template< typename object_t, typename super_t, typename field_t >
    248                 void apply(object_t *, field_t super_t::* field);
    249         };
    250 
    251         result1<ast::Stmt> call_accept( const ast::Stmt * );
    252         result1<ast::Expr> call_accept( const ast::Expr * );
     247        using generic_call_accept_result =
     248                std::enable_if<
     249                                !std::is_base_of<ast::Expr, node_t>::value &&
     250                                !std::is_base_of<ast::Stmt, node_t>::value
     251                        , __pass::result1<
     252                                typename std::remove_pointer< typename std::result_of<
     253                                        decltype(&node_t::accept)(node_t*, type&) >::type >::type
     254                        >
     255                >;
    253256
    254257        template< typename node_t >
    255258        auto call_accept( const node_t * node )
    256                 -> typename std::enable_if<
    257                                 !std::is_base_of<ast::Expr, node_t>::value &&
    258                                 !std::is_base_of<ast::Stmt, node_t>::value
    259                         , result1<
    260                                 typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    261                         >
    262                 >::type;
     259                -> typename generic_call_accept_result<node_t>::type;
    263260
    264261        // requests WithStmtsToAdd directly add to this statement, as if it is a compound.
    265         result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *);
    266 
    267         template<typename it_t, template <class...> class container_t>
    268                 static inline void take_all_delta( it_t it, container_t<ast::ptr<ast::Decl>> * decls, bool * mutated = nullptr ) {
    269                         if(empty(decls)) return;
    270 
    271                         std::transform(decls->begin(), decls->end(), it, [](ast::ptr<ast::Decl>&& decl) -> auto {
    272                                         auto loc = decl->location;
    273                                         auto stmt = new DeclStmt( loc, decl.release() );
    274                                         return { {stmt}, -1, false };
    275                                 });
    276                         decls->clear();
    277                         if(mutated) *mutated = true;
    278                 }
    279 
    280         // Container of statements
     262        __pass::result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *);
     263
    281264        template< template <class...> class container_t >
    282         struct resultNstmt {
    283                 struct delta {
    284                         ptr<Stmt> nval;
    285                         ssize_t old_idx;
    286                         bool is_old;
    287 
    288                         delta(const Stmt * s, ssize_t i, bool old) : nval{s}, old_idx{i}, is_old{old} {}
    289                 };
    290 
    291                 bool differs;
    292                 container_t< delta > values;
    293 
    294                 resultNstmt() : differs(false), values{} {}
    295                 resultNstmt(bool diff, container_t< delta > && vals) : differs(diff), values(vals) {}
    296 
    297                 template< typename object_t, typename super_t, typename field_t >
    298                 void apply(object_t *, field_t super_t::* field);
    299 
    300                 template< template <class...> class incontainer_t >
    301                 void take_all( incontainer_t<ast::ptr<ast::Stmt>> * stmts ) {
    302                         if(!stmts || stmts->empty()) return;
    303 
    304                         std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ), [](ast::ptr<ast::Stmt>& decl) -> delta {
    305                                         return delta( decl.release(), -1, false );
    306                                 });
    307                         stmts->clear();
    308                         differs = true;
    309                 }
    310 
    311                 template< template <class...> class incontainer_t >
    312                 void take_all( incontainer_t<ast::ptr<ast::Decl>> * decls ) {
    313                         if(!decls || decls->empty()) return;
    314 
    315                         std::transform(decls->begin(), decls->end(), std::back_inserter( values ), [](ast::ptr<ast::Decl>& decl) -> auto {
    316                                         auto loc = decl->location;
    317                                         auto stmt = new DeclStmt( loc, decl.release() );
    318                                         return delta( stmt, -1, false );
    319                                 });
    320                         decls->clear();
    321                         differs = true;
    322                 }
    323         };
    324 
    325         template< template <class...> class container_t >
    326         resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & );
    327 
    328         // Container of something
     265        __pass::resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & );
     266
    329267        template< template <class...> class container_t, typename node_t >
    330         struct resultN {
    331                 bool differs;
    332                 container_t<ptr<node_t>> values;
    333 
    334                 template< typename object_t, typename super_t, typename field_t >
    335                 void apply(object_t *, field_t super_t::* field);
    336         };
    337 
    338         template< template <class...> class container_t, typename node_t >
    339         resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container );
     268        __pass::resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container );
    340269
    341270public:
  • src/AST/Pass.impl.hpp

    rf5a51db rcc7bbe6  
    111111                }
    112112
    113 
    114113                //------------------------------
    115114                /// Check if value was mutated, different for pointers and containers
     
    125124        }
    126125
    127 
    128         template< typename core_t >
    129126        template< typename node_t >
    130127        template< typename object_t, typename super_t, typename field_t >
    131         void ast::Pass< core_t >::result1< node_t >::apply(object_t * object, field_t super_t::* field) {
     128        void __pass::result1< node_t >::apply( object_t * object, field_t super_t::* field ) {
    132129                object->*field = value;
    133130        }
     
    136133        template< typename node_t >
    137134        auto ast::Pass< core_t >::call_accept( const node_t * node )
    138                 -> typename std::enable_if<
    139                                 !std::is_base_of<ast::Expr, node_t>::value &&
    140                                 !std::is_base_of<ast::Stmt, node_t>::value
    141                         , ast::Pass< core_t >::result1<
    142                                 typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    143                         >
    144                 >::type
     135                -> typename ast::Pass< core_t >::template generic_call_accept_result<node_t>::type
    145136        {
    146137                __pedantic_pass_assert( __visit_children() );
     
    151142
    152143                auto nval = node->accept( *this );
    153                 ast::Pass< core_t >::result1<
     144                __pass::result1<
    154145                        typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    155146                > res;
     
    160151
    161152        template< typename core_t >
    162         ast::Pass< core_t >::result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
     153        __pass::template result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
    163154                __pedantic_pass_assert( __visit_children() );
    164155                __pedantic_pass_assert( expr );
     
    174165
    175166        template< typename core_t >
    176         ast::Pass< core_t >::result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
     167        __pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
    177168                __pedantic_pass_assert( __visit_children() );
    178169                __pedantic_pass_assert( stmt );
     
    183174
    184175        template< typename core_t >
    185         ast::Pass< core_t >::result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
     176        __pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
    186177                __pedantic_pass_assert( __visit_children() );
    187178                __pedantic_pass_assert( stmt );
     
    233224        }
    234225
    235         template< typename core_t >
    236226        template< template <class...> class container_t >
    237227        template< typename object_t, typename super_t, typename field_t >
    238         void ast::Pass< core_t >::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
     228        void __pass::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
    239229                auto & container = object->*field;
    240230                __pedantic_pass_assert( container.size() <= values.size() );
     
    243233
    244234                container_t<ptr<Stmt>> nvals;
    245                 for(delta & d : values) {
    246                         if( d.is_old ) {
     235                for (delta & d : values) {
     236                        if ( d.is_old ) {
    247237                                __pedantic_pass_assert( cit.idx <= d.old_idx );
    248238                                std::advance( cit, d.old_idx - cit.idx );
    249239                                nvals.push_back( std::move( (*cit).val) );
    250240                        } else {
    251                                 nvals.push_back( std::move(d.nval) );
     241                                nvals.push_back( std::move(d.new_val) );
    252242                        }
    253243                }
    254244
    255                 object->*field = std::move(nvals);
     245                container = std::move(nvals);
     246        }
     247
     248        template< template <class...> class container_t >
     249        template< template <class...> class incontainer_t >
     250        void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Stmt>> * stmts ) {
     251                if (!stmts || stmts->empty()) return;
     252
     253                std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ),
     254                        [](ast::ptr<ast::Stmt>& stmt) -> delta {
     255                                return delta( stmt.release(), -1, false );
     256                        });
     257                stmts->clear();
     258                differs = true;
     259        }
     260
     261        template< template<class...> class container_t >
     262        template< template<class...> class incontainer_t >
     263        void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Decl>> * decls ) {
     264                if (!decls || decls->empty()) return;
     265
     266                std::transform(decls->begin(), decls->end(), std::back_inserter( values ),
     267                        [](ast::ptr<ast::Decl>& decl) -> delta {
     268                                auto loc = decl->location;
     269                                auto stmt = new DeclStmt( loc, decl.release() );
     270                                return delta( stmt, -1, false );
     271                        });
     272                decls->clear();
     273                differs = true;
    256274        }
    257275
    258276        template< typename core_t >
    259277        template< template <class...> class container_t >
    260         ast::Pass< core_t >::resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
     278        __pass::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    261279                __pedantic_pass_assert( __visit_children() );
    262280                if( statements.empty() ) return {};
     
    285303                pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    286304
    287                 resultNstmt<container_t> new_kids;
     305                __pass::resultNstmt<container_t> new_kids;
    288306                for( auto value : enumerate( statements ) ) {
    289307                        try {
     
    327345        }
    328346
    329         template< typename core_t >
    330347        template< template <class...> class container_t, typename node_t >
    331348        template< typename object_t, typename super_t, typename field_t >
    332         void ast::Pass< core_t >::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
     349        void __pass::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
    333350                auto & container = object->*field;
    334351                __pedantic_pass_assert( container.size() == values.size() );
     
    346363        template< typename core_t >
    347364        template< template <class...> class container_t, typename node_t >
    348         ast::Pass< core_t >::resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
     365        __pass::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    349366                __pedantic_pass_assert( __visit_children() );
    350367                if( container.empty() ) return {};
     
    378395                if ( ! errors.isEmpty() ) { throw errors; }
    379396
    380                 return ast::Pass< core_t >::resultN<container_t, node_t>{ mutated, new_kids };
     397                return ast::__pass::resultN<container_t, node_t>{ mutated, new_kids };
    381398        }
    382399
  • src/AST/Pass.proto.hpp

    rf5a51db rcc7bbe6  
    2323class Pass;
    2424
    25 struct TranslationUnit;
     25class TranslationUnit;
    2626
    2727struct PureVisitor;
     
    123123                static constexpr bool value = std::is_void< ret_t >::value ||
    124124                        std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value;
     125        };
     126
     127        /// The result is a single node.
     128        template< typename node_t >
     129        struct result1 {
     130                bool differs;
     131                const node_t * value;
     132
     133                template< typename object_t, typename super_t, typename field_t >
     134                void apply( object_t *, field_t super_t::* field );
     135        };
     136
     137        /// The result is a container of statements.
     138        template< template<class...> class container_t >
     139        struct resultNstmt {
     140                /// The delta/change on a single node.
     141                struct delta {
     142                        ptr<Stmt> new_val;
     143                        ssize_t old_idx;
     144                        bool is_old;
     145
     146                        delta(const Stmt * s, ssize_t i, bool old) :
     147                                new_val(s), old_idx(i), is_old(old) {}
     148                };
     149
     150                bool differs;
     151                container_t< delta > values;
     152
     153                template< typename object_t, typename super_t, typename field_t >
     154                void apply( object_t *, field_t super_t::* field );
     155
     156                template< template<class...> class incontainer_t >
     157                void take_all( incontainer_t<ptr<Stmt>> * stmts );
     158
     159                template< template<class...> class incontainer_t >
     160                void take_all( incontainer_t<ptr<Decl>> * decls );
     161        };
     162
     163        /// The result is a container of nodes.
     164        template< template<class...> class container_t, typename node_t >
     165        struct resultN {
     166                bool differs;
     167                container_t<ptr<node_t>> values;
     168
     169                template< typename object_t, typename super_t, typename field_t >
     170                void apply( object_t *, field_t super_t::* field );
    125171        };
    126172
  • src/AST/TranslationUnit.hpp

    rf5a51db rcc7bbe6  
    2323namespace ast {
    2424
    25 struct TranslationUnit {
     25class TranslationUnit {
     26public:
    2627        std::list< ptr< Decl > > decls;
    2728
  • src/AST/module.mk

    rf5a51db rcc7bbe6  
    1616
    1717SRC_AST = \
    18         AST/AssertAcyclic.cpp \
    19         AST/AssertAcyclic.hpp \
    2018        AST/Attribute.cpp \
    2119        AST/Attribute.hpp \
     
    6462        AST/TypeSubstitution.cpp \
    6563        AST/TypeSubstitution.hpp \
     64        AST/Util.cpp \
     65        AST/Util.hpp \
    6666        AST/Visitor.hpp
    6767
  • src/CodeGen/FixNames.h

    rf5a51db rcc7bbe6  
    2020class Declaration;
    2121namespace ast {
    22         struct TranslationUnit;
     22        class TranslationUnit;
    2323}
    2424
  • src/Common/CodeLocation.h

    rf5a51db rcc7bbe6  
    3333
    3434        CodeLocation( const CodeLocation& rhs ) = default;
     35        CodeLocation( CodeLocation&& rhs ) = default;
     36        CodeLocation& operator=( const CodeLocation & ) = default;
     37        CodeLocation& operator=( CodeLocation && ) = default;
    3538
    3639        bool isSet () const {
  • src/Common/CodeLocationTools.hpp

    rf5a51db rcc7bbe6  
    1717
    1818namespace ast {
    19         struct TranslationUnit;
     19        class TranslationUnit;
    2020}
    2121
  • src/Common/ResolvProtoDump.hpp

    rf5a51db rcc7bbe6  
    1717
    1818namespace ast {
    19         struct TranslationUnit;
     19        class TranslationUnit;
    2020}
    2121
  • src/Concurrency/Waitfor.cc

    rf5a51db rcc7bbe6  
    372372                        ),
    373373                        new ListInit(
    374                                 map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
    375                                         Expression * init = new CastExpr(
    376                                                 new UntypedExpr(
    377                                                         new NameExpr( "get_monitor" ),
    378                                                         { expr }
    379                                                 ),
    380                                                 new PointerType(
    381                                                         noQualifiers,
    382                                                         new StructInstType(
    383                                                                 noQualifiers,
    384                                                                 decl_monitor
    385                                                         )
    386                                                 ),
    387                                                 false
    388                                         );
    389 
    390                                         ResolvExpr::findSingleExpression( init, indexer );
    391                                         return new SingleInit( init );
     374                                map_range < std::list<Initializer*> > ( clause.target.arguments, [](Expression * expr ){
     375                                        return new SingleInit( expr );
    392376                                })
    393377                        )
  • src/ControlStruct/MLEMutator.cc

    rf5a51db rcc7bbe6  
    6666
    6767        // break labels have to come after the statement they break out of, so mutate a statement, then if they inform us
    68         // through the breakLabel field tha they need a place to jump to on a break statement, add the break label to the
     68        // through the breakLabel field that they need a place to jump to on a break statement, add the break label to the
    6969        // body of statements
    7070        void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) {
  • src/ControlStruct/MultiLevelExit.cpp

    rf5a51db rcc7bbe6  
    176176        auto mutStmt = mutate( stmt );
    177177        // A child statement may set the break label.
    178         mutStmt->kids = move( fixBlock( stmt->kids, false ) );
     178        mutStmt->kids = fixBlock( stmt->kids, false );
    179179
    180180        if ( isLabeled ) {
  • src/InitTweak/FixInit.h

    rf5a51db rcc7bbe6  
    2121class Declaration;
    2222namespace ast {
    23         struct TranslationUnit;
     23        class TranslationUnit;
    2424}
    2525
  • src/MakeLibCfa.h

    rf5a51db rcc7bbe6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // MakeLibCfa.h -- 
     7// MakeLibCfa.h --
    88//
    99// Author           : Richard C. Bilson
     
    2020class Declaration;
    2121namespace ast {
    22         struct TranslationUnit;
     22        class TranslationUnit;
    2323}
    2424
  • src/Makefile.am

    rf5a51db rcc7bbe6  
    5959
    6060$(srcdir)/AST/Type.hpp : BasicTypes-gen.cc
    61         ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
     61        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra -Werror=return-type
    6262        @./BasicTypes-gen
    6363        @rm BasicTypes-gen
     
    7171EXTRA_DIST = include/cassert include/optional BasicTypes-gen.cc
    7272
    73 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG)
     73AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -Werror=return-type -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG)
    7474AM_LDFLAGS  = @HOST_FLAGS@ -Xlinker -export-dynamic
    7575ARFLAGS     = cr
  • src/Parser/parser.yy

    rf5a51db rcc7bbe6  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  1 11:06:13 2022
    13 // Update Count     : 5167
     12// Last Modified On : Sat Feb 19 09:47:20 2022
     13// Update Count     : 5218
    1414//
    1515
     
    10521052        identifier_or_type_name ':' attribute_list_opt statement
    10531053                { $$ = $4->add_label( $1, $3 ); }
     1054        | identifier_or_type_name ':' attribute_list_opt error
     1055                { SemanticError( yylloc, "previous label must be associated with a statement (where a declaration is not a statement). Move the label or terminate with a semi-colon." ); $$ = nullptr; }
    10541056        ;
    10551057
     
    10861088        | statement_list_nodecl statement
    10871089                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
     1090        | statement_list_nodecl error
     1091                { SemanticError( yylloc, "declarations only allowed at the start of the switch body, i.e., after the '{'." ); $$ = nullptr; }
    10881092        ;
    10891093
     
    10931097        | MUTEX '(' ')' comma_expression ';'
    10941098                { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); }
    1095                 // { SemanticError( yylloc, "Mutex expression is currently unimplemented." ); $$ = nullptr; }
    10961099        ;
    10971100
     
    11131116                        $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    11141117                }
     1118        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA
     1119                { SemanticError( yylloc, "only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    11151120        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    11161121                { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
     
    11201125                        $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    11211126                }
     1127        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA
     1128                { SemanticError( yylloc, "only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    11221129        ;
    11231130
     
    11581165
    11591166case_label:                                                                                             // CFA
    1160         CASE case_value_list ':'                                        { $$ = $2; }
     1167        CASE error
     1168                { SemanticError( yylloc, "missing case list after case." ); $$ = nullptr; }
     1169        | CASE case_value_list ':'                                      { $$ = $2; }
     1170        | CASE case_value_list error
     1171                { SemanticError( yylloc, "missing colon after case list." ); $$ = nullptr; }
    11611172        | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
    11621173                // A semantic check is required to ensure only one default clause per switch/choose statement.
    1163         ;
    1164 
    1165 //label_list_opt:
    1166 //      // empty
    1167 //      | identifier_or_type_name ':'
    1168 //      | label_list_opt identifier_or_type_name ':'
    1169 //      ;
     1174        | DEFAULT error
     1175                { SemanticError( yylloc, "missing colon after default." ); $$ = nullptr; }
     1176        ;
    11701177
    11711178case_label_list:                                                                                // CFA
     
    11971204                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
    11981205        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1199                 // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
    12001206                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    12011207        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
     
    12041210                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
    12051211        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1206                 // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
    12071212                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
    12081213        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
     
    12111216                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
    12121217        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1213                 // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
    12141218                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
    12151219        ;
     
    27292733        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    27302734                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
     2735        | EXTERN STRINGliteral
     2736                {
     2737                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
     2738                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
     2739                }
     2740          up external_definition down
     2741                {
     2742                        linkage = linkageStack.top();
     2743                        linkageStack.pop();
     2744                        $$ = $5;
     2745                }
    27312746        | EXTERN STRINGliteral                                                          // C++-style linkage specifier
    27322747                {
  • src/ResolvExpr/Resolver.cc

    rf5a51db rcc7bbe6  
    11121112                }
    11131113
    1114                
     1114
    11151115        } // anonymous namespace
    11161116/// Establish post-resolver invariants for expressions
     
    11581158
    11591159        namespace {
    1160                
     1160
    11611161
    11621162                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     
    19051905
    19061906                        clause2.target.args.reserve( clause.target.args.size() );
     1907                        const ast::StructDecl * decl_monitor = symtab.lookupStruct( "monitor$" );
    19071908                        for ( auto arg : argsCandidates.front() ) {
    1908                                 clause2.target.args.emplace_back( std::move( arg->expr ) );
     1909                                const auto & loc = stmt->location;
     1910
     1911                                ast::Expr * init = new ast::CastExpr( loc,
     1912                                        new ast::UntypedExpr( loc,
     1913                                                new ast::NameExpr( loc, "get_monitor" ),
     1914                                                { arg->expr }
     1915                                        ),
     1916                                        new ast::PointerType(
     1917                                                new ast::StructInstType(
     1918                                                        decl_monitor
     1919                                                )
     1920                                        )
     1921                                );
     1922
     1923                                clause2.target.args.emplace_back( findSingleExpression( init, symtab ) );
    19091924                        }
    19101925
     
    20772092                if (auto functionDecl = decl.as<ast::FunctionDecl>()) {
    20782093                        // xxx - can intrinsic gen ever fail?
    2079                         if (functionDecl->linkage == ast::Linkage::AutoGen) { 
     2094                        if (functionDecl->linkage == ast::Linkage::AutoGen) {
    20802095                                auto mutDecl = mutate(functionDecl);
    20812096                                mutDecl->isDeleted = true;
  • src/ResolvExpr/Resolver.h

    rf5a51db rcc7bbe6  
    3535        class StmtExpr;
    3636        class SymbolTable;
    37         struct TranslationUnit;
     37        class TranslationUnit;
    3838        class Type;
    3939        class TypeEnvironment;
     
    7272        ast::ptr< ast::Init > resolveCtorInit(
    7373                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab );
    74         /// Resolves a statement expression 
     74        /// Resolves a statement expression
    7575        const ast::Expr * resolveStmtExpr(
    7676                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab );
  • src/SymTab/Validate.cc

    rf5a51db rcc7bbe6  
    194194        };
    195195
     196        // These structs are the sub-sub-passes of ForallPointerDecay_old.
     197
     198        struct TraitExpander_old final {
     199                void previsit( FunctionType * );
     200                void previsit( StructDecl * );
     201                void previsit( UnionDecl * );
     202        };
     203
     204        struct AssertionFixer_old final {
     205                void previsit( FunctionType * );
     206                void previsit( StructDecl * );
     207                void previsit( UnionDecl * );
     208        };
     209
     210        struct CheckOperatorTypes_old final {
     211                void previsit( ObjectDecl * );
     212        };
     213
     214        struct FixUniqueIds_old final {
     215                void previsit( DeclarationWithType * );
     216        };
     217
    196218        struct ReturnChecker : public WithGuards {
    197219                /// Checks that return statements return nothing if their return type is void
     
    386408
    387409        void validate_D( std::list< Declaration * > & translationUnit ) {
    388                 PassVisitor<ForallPointerDecay_old> fpd;
    389410                {
    390411                        Stats::Heap::newPass("validate-D");
     
    394415                        });
    395416                        Stats::Time::TimeBlock("Forall Pointer Decay", [&]() {
    396                                 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     417                                decayForallPointers( translationUnit ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    397418                        });
    398419                        Stats::Time::TimeBlock("Hoist Control Declarations", [&]() {
     
    454475
    455476        void decayForallPointers( std::list< Declaration * > & translationUnit ) {
    456                 PassVisitor<ForallPointerDecay_old> fpd;
    457                 acceptAll( translationUnit, fpd );
     477                PassVisitor<TraitExpander_old> te;
     478                acceptAll( translationUnit, te );
     479                PassVisitor<AssertionFixer_old> af;
     480                acceptAll( translationUnit, af );
     481                PassVisitor<CheckOperatorTypes_old> cot;
     482                acceptAll( translationUnit, cot );
     483                PassVisitor<FixUniqueIds_old> fui;
     484                acceptAll( translationUnit, fui );
     485        }
     486
     487        void decayForallPointersA( std::list< Declaration * > & translationUnit ) {
     488                PassVisitor<TraitExpander_old> te;
     489                acceptAll( translationUnit, te );
     490        }
     491        void decayForallPointersB( std::list< Declaration * > & translationUnit ) {
     492                PassVisitor<AssertionFixer_old> af;
     493                acceptAll( translationUnit, af );
     494        }
     495        void decayForallPointersC( std::list< Declaration * > & translationUnit ) {
     496                PassVisitor<CheckOperatorTypes_old> cot;
     497                acceptAll( translationUnit, cot );
     498        }
     499        void decayForallPointersD( std::list< Declaration * > & translationUnit ) {
     500                PassVisitor<FixUniqueIds_old> fui;
     501                acceptAll( translationUnit, fui );
    458502        }
    459503
     
    470514                PassVisitor<EnumAndPointerDecay_old> epc;
    471515                PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
    472                 PassVisitor<ForallPointerDecay_old> fpd;
     516                PassVisitor<TraitExpander_old> te;
     517                PassVisitor<AssertionFixer_old> af;
     518                PassVisitor<CheckOperatorTypes_old> cot;
     519                PassVisitor<FixUniqueIds_old> fui;
    473520                type->accept( epc );
    474521                type->accept( lrt );
    475                 type->accept( fpd );
     522                type->accept( te );
     523                type->accept( af );
     524                type->accept( cot );
     525                type->accept( fui );
    476526        }
    477527
     
    9721022        }
    9731023
     1024        /// Replace all traits in assertion lists with their assertions.
     1025        void expandTraits( std::list< TypeDecl * > & forall ) {
     1026                for ( TypeDecl * type : forall ) {
     1027                        std::list< DeclarationWithType * > asserts;
     1028                        asserts.splice( asserts.end(), type->assertions );
     1029                        // expand trait instances into their members
     1030                        for ( DeclarationWithType * assertion : asserts ) {
     1031                                if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     1032                                        // expand trait instance into all of its members
     1033                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     1034                                        delete traitInst;
     1035                                } else {
     1036                                        // pass other assertions through
     1037                                        type->assertions.push_back( assertion );
     1038                                } // if
     1039                        } // for
     1040                }
     1041        }
     1042
     1043        /// Fix each function in the assertion list and check for invalid void type.
     1044        void fixAssertions(
     1045                        std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) {
     1046                for ( TypeDecl * type : forall ) {
     1047                        for ( DeclarationWithType *& assertion : type->assertions ) {
     1048                                bool isVoid = fixFunction( assertion );
     1049                                if ( isVoid ) {
     1050                                        SemanticError( node, "invalid type void in assertion of function " );
     1051                                } // if
     1052                        } // for
     1053                }
     1054        }
     1055
    9741056        void ForallPointerDecay_old::previsit( ObjectDecl * object ) {
    9751057                // ensure that operator names only apply to functions or function pointers
     
    9941076        void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) {
    9951077                forallFixer( aggrDecl->parameters, aggrDecl );
     1078        }
     1079
     1080        void TraitExpander_old::previsit( FunctionType * ftype ) {
     1081                expandTraits( ftype->forall );
     1082        }
     1083
     1084        void TraitExpander_old::previsit( StructDecl * aggrDecl ) {
     1085                expandTraits( aggrDecl->parameters );
     1086        }
     1087
     1088        void TraitExpander_old::previsit( UnionDecl * aggrDecl ) {
     1089                expandTraits( aggrDecl->parameters );
     1090        }
     1091
     1092        void AssertionFixer_old::previsit( FunctionType * ftype ) {
     1093                fixAssertions( ftype->forall, ftype );
     1094        }
     1095
     1096        void AssertionFixer_old::previsit( StructDecl * aggrDecl ) {
     1097                fixAssertions( aggrDecl->parameters, aggrDecl );
     1098        }
     1099
     1100        void AssertionFixer_old::previsit( UnionDecl * aggrDecl ) {
     1101                fixAssertions( aggrDecl->parameters, aggrDecl );
     1102        }
     1103
     1104        void CheckOperatorTypes_old::previsit( ObjectDecl * object ) {
     1105                // ensure that operator names only apply to functions or function pointers
     1106                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     1107                        SemanticError( object->location, toCString( "operator ", object->name.c_str(), " is not a function or function pointer." )  );
     1108                }
     1109        }
     1110
     1111        void FixUniqueIds_old::previsit( DeclarationWithType * decl ) {
     1112                decl->fixUniqueId();
    9961113        }
    9971114
  • src/SymTab/Validate.h

    rf5a51db rcc7bbe6  
    4343        void validate_F( std::list< Declaration * > &translationUnit );
    4444        void decayForallPointers( std::list< Declaration * > & translationUnit );
     45        void decayForallPointersA( std::list< Declaration * > & translationUnit );
     46        void decayForallPointersB( std::list< Declaration * > & translationUnit );
     47        void decayForallPointersC( std::list< Declaration * > & translationUnit );
     48        void decayForallPointersD( std::list< Declaration * > & translationUnit );
    4549
    4650        const ast::Type * validateType(
  • src/Validate/module.mk

    rf5a51db rcc7bbe6  
    2020        Validate/CompoundLiteral.cpp \
    2121        Validate/CompoundLiteral.hpp \
     22        Validate/ForallPointerDecay.cpp \
     23        Validate/ForallPointerDecay.hpp \
    2224        Validate/HandleAttributes.cc \
    2325        Validate/HandleAttributes.h \
  • src/main.cc

    rf5a51db rcc7bbe6  
    3232
    3333#include "AST/Convert.hpp"
     34#include "AST/Print.hpp"
    3435#include "CompilationState.h"
    3536#include "../config.h"                      // for CFA_LIBDIR
     
    7677#include "Validate/Autogen.hpp"             // for autogenerateRoutines
    7778#include "Validate/FindSpecialDecls.h"      // for findGlobalDecls
     79#include "Validate/ForallPointerDecay.hpp"  // for decayForallPointers
    7880#include "Validate/CompoundLiteral.hpp"     // for handleCompoundLiterals
    7981#include "Validate/InitializerLength.hpp"   // for setLengthFromInitializer
     
    331333
    332334                if( useNewAST ) {
    333                         PASS( "Apply Concurrent Keywords", Concurrency::applyKeywords( translationUnit ) );
    334                         PASS( "Forall Pointer Decay", SymTab::decayForallPointers( translationUnit ) );
     335                        PASS( "Implement Concurrent Keywords", Concurrency::applyKeywords( translationUnit ) );
     336                        //PASS( "Forall Pointer Decay - A", SymTab::decayForallPointersA( translationUnit ) );
     337                        //PASS( "Forall Pointer Decay - B", SymTab::decayForallPointersB( translationUnit ) );
     338                        //PASS( "Forall Pointer Decay - C", SymTab::decayForallPointersC( translationUnit ) );
     339                        //PASS( "Forall Pointer Decay - D", SymTab::decayForallPointersD( translationUnit ) );
    335340                        CodeTools::fillLocations( translationUnit );
    336341
     
    342347
    343348                        forceFillCodeLocations( transUnit );
     349
     350                        // Must be after implement concurrent keywords; because uniqueIds
     351                        //   must be set on declaration before resolution.
     352                        // Must happen before autogen routines are added.
     353                        PASS( "Forall Pointer Decay", Validate::decayForallPointers( transUnit ) );
    344354
    345355                        // Must happen before autogen routines are added.
Note: See TracChangeset for help on using the changeset viewer.