- Timestamp:
- Feb 23, 2022, 11:24:34 AM (4 years ago)
- 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. - Location:
- src
- Files:
-
- 4 added
- 2 deleted
- 25 edited
-
AST/AssertAcyclic.cpp (deleted)
-
AST/AssertAcyclic.hpp (deleted)
-
AST/Convert.hpp (modified) (1 diff)
-
AST/Decl.cpp (modified) (1 diff)
-
AST/Fwd.hpp (modified) (1 diff)
-
AST/Pass.hpp (modified) (1 diff)
-
AST/Pass.impl.hpp (modified) (13 diffs)
-
AST/Pass.proto.hpp (modified) (2 diffs)
-
AST/TranslationUnit.hpp (modified) (1 diff)
-
AST/Util.cpp (added)
-
AST/Util.hpp (added)
-
AST/module.mk (modified) (2 diffs)
-
CodeGen/FixNames.h (modified) (1 diff)
-
Common/CodeLocation.h (modified) (1 diff)
-
Common/CodeLocationTools.hpp (modified) (1 diff)
-
Common/ResolvProtoDump.hpp (modified) (1 diff)
-
Concurrency/Waitfor.cc (modified) (1 diff)
-
ControlStruct/MLEMutator.cc (modified) (1 diff)
-
ControlStruct/MultiLevelExit.cpp (modified) (1 diff)
-
InitTweak/FixInit.h (modified) (1 diff)
-
MakeLibCfa.h (modified) (2 diffs)
-
Makefile.am (modified) (2 diffs)
-
Parser/parser.yy (modified) (11 diffs)
-
ResolvExpr/Resolver.cc (modified) (4 diffs)
-
ResolvExpr/Resolver.h (modified) (2 diffs)
-
SymTab/Validate.cc (modified) (7 diffs)
-
SymTab/Validate.h (modified) (1 diff)
-
Validate/ForallPointerDecay.cpp (added)
-
Validate/ForallPointerDecay.hpp (added)
-
Validate/module.mk (modified) (1 diff)
-
main.cc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.hpp
rf5a51db rcc7bbe6 20 20 class Declaration; 21 21 namespace ast { 22 structTranslationUnit;22 class TranslationUnit; 23 23 }; 24 24 -
src/AST/Decl.cpp
rf5a51db rcc7bbe6 39 39 if ( uniqueId ) return; // ensure only set once 40 40 uniqueId = ++lastUniqueId; 41 idMap[ uniqueId ] = this; 41 // The extra readonly pointer is causing some reference counting issues. 42 // idMap[ uniqueId ] = this; 42 43 } 43 44 44 45 readonly<Decl> Decl::fromId( UniqueId id ) { 46 // Right now this map is always empty, so don't use it. 47 assert( false ); 45 48 IdMapType::const_iterator i = idMap.find( id ); 46 49 if ( i != idMap.end() ) return i->second; -
src/AST/Fwd.hpp
rf5a51db rcc7bbe6 140 140 typedef unsigned int UniqueId; 141 141 142 structTranslationUnit;142 class TranslationUnit; 143 143 // TODO: Get from the TranslationUnit: 144 144 extern ptr<Type> sizeType; -
src/AST/Pass.hpp
rf5a51db rcc7bbe6 239 239 private: 240 240 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. 242 246 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 >; 253 256 254 257 template< typename node_t > 255 258 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; 263 260 264 261 // 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 281 264 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 329 267 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 ); 340 269 341 270 public: -
src/AST/Pass.impl.hpp
rf5a51db rcc7bbe6 111 111 } 112 112 113 114 113 //------------------------------ 115 114 /// Check if value was mutated, different for pointers and containers … … 125 124 } 126 125 127 128 template< typename core_t >129 126 template< typename node_t > 130 127 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 ) { 132 129 object->*field = value; 133 130 } … … 136 133 template< typename node_t > 137 134 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 145 136 { 146 137 __pedantic_pass_assert( __visit_children() ); … … 151 142 152 143 auto nval = node->accept( *this ); 153 ast::Pass< core_t >::result1<144 __pass::result1< 154 145 typename std::remove_pointer< decltype( node->accept(*this) ) >::type 155 146 > res; … … 160 151 161 152 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 ) { 163 154 __pedantic_pass_assert( __visit_children() ); 164 155 __pedantic_pass_assert( expr ); … … 174 165 175 166 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 ) { 177 168 __pedantic_pass_assert( __visit_children() ); 178 169 __pedantic_pass_assert( stmt ); … … 183 174 184 175 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 ) { 186 177 __pedantic_pass_assert( __visit_children() ); 187 178 __pedantic_pass_assert( stmt ); … … 233 224 } 234 225 235 template< typename core_t >236 226 template< template <class...> class container_t > 237 227 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) { 239 229 auto & container = object->*field; 240 230 __pedantic_pass_assert( container.size() <= values.size() ); … … 243 233 244 234 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 ) { 247 237 __pedantic_pass_assert( cit.idx <= d.old_idx ); 248 238 std::advance( cit, d.old_idx - cit.idx ); 249 239 nvals.push_back( std::move( (*cit).val) ); 250 240 } else { 251 nvals.push_back( std::move(d.n val) );241 nvals.push_back( std::move(d.new_val) ); 252 242 } 253 243 } 254 244 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; 256 274 } 257 275 258 276 template< typename core_t > 259 277 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 ) { 261 279 __pedantic_pass_assert( __visit_children() ); 262 280 if( statements.empty() ) return {}; … … 285 303 pass_visitor_stats.avg->push(pass_visitor_stats.depth); 286 304 287 resultNstmt<container_t> new_kids;305 __pass::resultNstmt<container_t> new_kids; 288 306 for( auto value : enumerate( statements ) ) { 289 307 try { … … 327 345 } 328 346 329 template< typename core_t >330 347 template< template <class...> class container_t, typename node_t > 331 348 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) { 333 350 auto & container = object->*field; 334 351 __pedantic_pass_assert( container.size() == values.size() ); … … 346 363 template< typename core_t > 347 364 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 ) { 349 366 __pedantic_pass_assert( __visit_children() ); 350 367 if( container.empty() ) return {}; … … 378 395 if ( ! errors.isEmpty() ) { throw errors; } 379 396 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 }; 381 398 } 382 399 -
src/AST/Pass.proto.hpp
rf5a51db rcc7bbe6 23 23 class Pass; 24 24 25 structTranslationUnit;25 class TranslationUnit; 26 26 27 27 struct PureVisitor; … … 123 123 static constexpr bool value = std::is_void< ret_t >::value || 124 124 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 ); 125 171 }; 126 172 -
src/AST/TranslationUnit.hpp
rf5a51db rcc7bbe6 23 23 namespace ast { 24 24 25 struct TranslationUnit { 25 class TranslationUnit { 26 public: 26 27 std::list< ptr< Decl > > decls; 27 28 -
src/AST/module.mk
rf5a51db rcc7bbe6 16 16 17 17 SRC_AST = \ 18 AST/AssertAcyclic.cpp \19 AST/AssertAcyclic.hpp \20 18 AST/Attribute.cpp \ 21 19 AST/Attribute.hpp \ … … 64 62 AST/TypeSubstitution.cpp \ 65 63 AST/TypeSubstitution.hpp \ 64 AST/Util.cpp \ 65 AST/Util.hpp \ 66 66 AST/Visitor.hpp 67 67 -
src/CodeGen/FixNames.h
rf5a51db rcc7bbe6 20 20 class Declaration; 21 21 namespace ast { 22 structTranslationUnit;22 class TranslationUnit; 23 23 } 24 24 -
src/Common/CodeLocation.h
rf5a51db rcc7bbe6 33 33 34 34 CodeLocation( const CodeLocation& rhs ) = default; 35 CodeLocation( CodeLocation&& rhs ) = default; 36 CodeLocation& operator=( const CodeLocation & ) = default; 37 CodeLocation& operator=( CodeLocation && ) = default; 35 38 36 39 bool isSet () const { -
src/Common/CodeLocationTools.hpp
rf5a51db rcc7bbe6 17 17 18 18 namespace ast { 19 structTranslationUnit;19 class TranslationUnit; 20 20 } 21 21 -
src/Common/ResolvProtoDump.hpp
rf5a51db rcc7bbe6 17 17 18 18 namespace ast { 19 structTranslationUnit;19 class TranslationUnit; 20 20 } 21 21 -
src/Concurrency/Waitfor.cc
rf5a51db rcc7bbe6 372 372 ), 373 373 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 ); 392 376 }) 393 377 ) -
src/ControlStruct/MLEMutator.cc
rf5a51db rcc7bbe6 66 66 67 67 // 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 the68 // through the breakLabel field that they need a place to jump to on a break statement, add the break label to the 69 69 // body of statements 70 70 void MultiLevelExitMutator::fixBlock( std::list< Statement * > &kids, bool caseClause ) { -
src/ControlStruct/MultiLevelExit.cpp
rf5a51db rcc7bbe6 176 176 auto mutStmt = mutate( stmt ); 177 177 // A child statement may set the break label. 178 mutStmt->kids = move( fixBlock( stmt->kids, false ));178 mutStmt->kids = fixBlock( stmt->kids, false ); 179 179 180 180 if ( isLabeled ) { -
src/InitTweak/FixInit.h
rf5a51db rcc7bbe6 21 21 class Declaration; 22 22 namespace ast { 23 structTranslationUnit;23 class TranslationUnit; 24 24 } 25 25 -
src/MakeLibCfa.h
rf5a51db rcc7bbe6 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // MakeLibCfa.h -- 7 // MakeLibCfa.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 20 20 class Declaration; 21 21 namespace ast { 22 structTranslationUnit;22 class TranslationUnit; 23 23 } 24 24 -
src/Makefile.am
rf5a51db rcc7bbe6 59 59 60 60 $(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 62 62 @./BasicTypes-gen 63 63 @rm BasicTypes-gen … … 71 71 EXTRA_DIST = include/cassert include/optional BasicTypes-gen.cc 72 72 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)73 AM_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) 74 74 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 75 75 ARFLAGS = cr -
src/Parser/parser.yy
rf5a51db rcc7bbe6 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Feb 1 11:06:13202213 // Update Count : 5 16712 // Last Modified On : Sat Feb 19 09:47:20 2022 13 // Update Count : 5218 14 14 // 15 15 … … 1052 1052 identifier_or_type_name ':' attribute_list_opt statement 1053 1053 { $$ = $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; } 1054 1056 ; 1055 1057 … … 1086 1088 | statement_list_nodecl statement 1087 1089 { 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; } 1088 1092 ; 1089 1093 … … 1093 1097 | MUTEX '(' ')' comma_expression ';' 1094 1098 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); } 1095 // { SemanticError( yylloc, "Mutex expression is currently unimplemented." ); $$ = nullptr; }1096 1099 ; 1097 1100 … … 1113 1116 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1114 1117 } 1118 | SWITCH '(' comma_expression ')' '{' error '}' // CFA 1119 { SemanticError( yylloc, "only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1115 1120 | CHOOSE '(' comma_expression ')' case_clause // CFA 1116 1121 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } … … 1120 1125 $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw; 1121 1126 } 1127 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA 1128 { SemanticError( yylloc, "only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1122 1129 ; 1123 1130 … … 1158 1165 1159 1166 case_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; } 1161 1172 | DEFAULT ':' { $$ = new StatementNode( build_default() ); } 1162 1173 // 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 ; 1170 1177 1171 1178 case_label_list: // CFA … … 1197 1204 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } 1198 1205 | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA 1199 // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }1200 1206 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); } 1201 1207 | DO statement WHILE '(' ')' ';' // CFA => do while( 1 ) … … 1204 1210 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1205 1211 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1206 // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }1207 1212 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); } 1208 1213 | FOR '(' ')' statement // CFA => for ( ;; ) … … 1211 1216 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } 1212 1217 | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA 1213 // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }1214 1218 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); } 1215 1219 ; … … 2729 2733 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 2730 2734 { $$ = 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 } 2731 2746 | EXTERN STRINGliteral // C++-style linkage specifier 2732 2747 { -
src/ResolvExpr/Resolver.cc
rf5a51db rcc7bbe6 1112 1112 } 1113 1113 1114 1114 1115 1115 } // anonymous namespace 1116 1116 /// Establish post-resolver invariants for expressions … … 1158 1158 1159 1159 namespace { 1160 1160 1161 1161 1162 1162 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the … … 1905 1905 1906 1906 clause2.target.args.reserve( clause.target.args.size() ); 1907 const ast::StructDecl * decl_monitor = symtab.lookupStruct( "monitor$" ); 1907 1908 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 ) ); 1909 1924 } 1910 1925 … … 2077 2092 if (auto functionDecl = decl.as<ast::FunctionDecl>()) { 2078 2093 // xxx - can intrinsic gen ever fail? 2079 if (functionDecl->linkage == ast::Linkage::AutoGen) { 2094 if (functionDecl->linkage == ast::Linkage::AutoGen) { 2080 2095 auto mutDecl = mutate(functionDecl); 2081 2096 mutDecl->isDeleted = true; -
src/ResolvExpr/Resolver.h
rf5a51db rcc7bbe6 35 35 class StmtExpr; 36 36 class SymbolTable; 37 structTranslationUnit;37 class TranslationUnit; 38 38 class Type; 39 39 class TypeEnvironment; … … 72 72 ast::ptr< ast::Init > resolveCtorInit( 73 73 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab ); 74 /// Resolves a statement expression 74 /// Resolves a statement expression 75 75 const ast::Expr * resolveStmtExpr( 76 76 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab ); -
src/SymTab/Validate.cc
rf5a51db rcc7bbe6 194 194 }; 195 195 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 196 218 struct ReturnChecker : public WithGuards { 197 219 /// Checks that return statements return nothing if their return type is void … … 386 408 387 409 void validate_D( std::list< Declaration * > & translationUnit ) { 388 PassVisitor<ForallPointerDecay_old> fpd;389 410 { 390 411 Stats::Heap::newPass("validate-D"); … … 394 415 }); 395 416 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 resolution417 decayForallPointers( translationUnit ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution 397 418 }); 398 419 Stats::Time::TimeBlock("Hoist Control Declarations", [&]() { … … 454 475 455 476 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 ); 458 502 } 459 503 … … 470 514 PassVisitor<EnumAndPointerDecay_old> epc; 471 515 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; 473 520 type->accept( epc ); 474 521 type->accept( lrt ); 475 type->accept( fpd ); 522 type->accept( te ); 523 type->accept( af ); 524 type->accept( cot ); 525 type->accept( fui ); 476 526 } 477 527 … … 972 1022 } 973 1023 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 974 1056 void ForallPointerDecay_old::previsit( ObjectDecl * object ) { 975 1057 // ensure that operator names only apply to functions or function pointers … … 994 1076 void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) { 995 1077 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(); 996 1113 } 997 1114 -
src/SymTab/Validate.h
rf5a51db rcc7bbe6 43 43 void validate_F( std::list< Declaration * > &translationUnit ); 44 44 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 ); 45 49 46 50 const ast::Type * validateType( -
src/Validate/module.mk
rf5a51db rcc7bbe6 20 20 Validate/CompoundLiteral.cpp \ 21 21 Validate/CompoundLiteral.hpp \ 22 Validate/ForallPointerDecay.cpp \ 23 Validate/ForallPointerDecay.hpp \ 22 24 Validate/HandleAttributes.cc \ 23 25 Validate/HandleAttributes.h \ -
src/main.cc
rf5a51db rcc7bbe6 32 32 33 33 #include "AST/Convert.hpp" 34 #include "AST/Print.hpp" 34 35 #include "CompilationState.h" 35 36 #include "../config.h" // for CFA_LIBDIR … … 76 77 #include "Validate/Autogen.hpp" // for autogenerateRoutines 77 78 #include "Validate/FindSpecialDecls.h" // for findGlobalDecls 79 #include "Validate/ForallPointerDecay.hpp" // for decayForallPointers 78 80 #include "Validate/CompoundLiteral.hpp" // for handleCompoundLiterals 79 81 #include "Validate/InitializerLength.hpp" // for setLengthFromInitializer … … 331 333 332 334 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 ) ); 335 340 CodeTools::fillLocations( translationUnit ); 336 341 … … 342 347 343 348 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 ) ); 344 354 345 355 // Must happen before autogen routines are added.
Note:
See TracChangeset
for help on using the changeset viewer.