- Timestamp:
- May 12, 2022, 3:10:58 PM (4 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 8060b2b, f835806
- Parents:
- f75e25b (diff), 491bb81 (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:
-
- 16 edited
-
AST/Convert.cpp (modified) (3 diffs)
-
AST/Copy.cpp (modified) (2 diffs)
-
AST/Decl.cpp (modified) (3 diffs)
-
AST/Decl.hpp (modified) (2 diffs)
-
AST/Expr.hpp (modified) (1 diff)
-
AST/Label.hpp (modified) (1 diff)
-
AST/Node.hpp (modified) (2 diffs)
-
AST/Pass.proto.hpp (modified) (3 diffs)
-
AST/Stmt.cpp (modified) (2 diffs)
-
AST/Stmt.hpp (modified) (2 diffs)
-
AST/Util.cpp (modified) (3 diffs)
-
Common/CodeLocationTools.cpp (modified) (4 diffs)
-
ControlStruct/LabelGeneratorNew.hpp (modified) (1 diff)
-
ControlStruct/MultiLevelExit.cpp (modified) (5 diffs)
-
Parser/parser.yy (modified) (3 diffs)
-
Validate/Autogen.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rf75e25b re5628db 93 93 }; 94 94 95 template<typename T>96 Getter<T> get() {97 return Getter<T>{ *this };98 }95 template<typename T> 96 Getter<T> get() { 97 return Getter<T>{ *this }; 98 } 99 99 100 100 Label makeLabel(Statement * labelled, const ast::Label& label) { … … 1651 1651 // GET_ACCEPT_1(type, FunctionType), 1652 1652 std::move(forall), 1653 std::move(assertions), 1653 1654 std::move(paramVars), 1654 1655 std::move(returnVars), … … 1664 1665 cache.emplace( old, decl ); 1665 1666 1666 decl->assertions = std::move(assertions);1667 1667 decl->withExprs = GET_ACCEPT_V(withExprs, Expr); 1668 1668 decl->stmts = GET_ACCEPT_1(statements, CompoundStmt); -
src/AST/Copy.cpp
rf75e25b re5628db 10 10 // Created On : Thr Nov 11 9:16:00 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Nov 11 9:28:00 202113 // Update Count : 012 // Last Modified On : Tue May 3 16:28:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 77 77 } 78 78 79 void postvisit( const UniqueExpr * node ) { 80 readonlyInsert( &node->object ); 81 } 82 79 83 void postvisit( const MemberExpr * node ) { 80 84 readonlyInsert( &node->member ); -
src/AST/Decl.cpp
rf75e25b re5628db 9 9 // Author : Aaron B. Moss 10 10 // Created On : Thu May 9 10:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Jan 12 16:54:55 202113 // Update Count : 2 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu May 5 12:10:00 2022 13 // Update Count : 24 14 14 // 15 15 … … 53 53 // --- FunctionDecl 54 54 55 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 55 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name, 56 56 std::vector<ptr<TypeDecl>>&& forall, 57 57 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, … … 74 74 } 75 75 this->type = ftype; 76 } 77 78 FunctionDecl::FunctionDecl( const CodeLocation & location, const std::string & name, 79 std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions, 80 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 81 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 82 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 83 : DeclWithType( location, name, storage, linkage, std::move(attrs), fs ), 84 params( std::move(params) ), returns( std::move(returns) ), 85 type_params( std::move( forall) ), assertions( std::move( assertions ) ), 86 type( nullptr ), stmts( stmts ) { 87 FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs ); 88 for ( auto & param : this->params ) { 89 type->params.emplace_back( param->get_type() ); 90 } 91 for ( auto & ret : this->returns ) { 92 type->returns.emplace_back( ret->get_type() ); 93 } 94 for ( auto & param : this->type_params ) { 95 type->forall.emplace_back( new TypeInstType( param ) ); 96 } 97 for ( auto & assertion : this->assertions ) { 98 type->assertions.emplace_back( 99 new VariableExpr( assertion->location, assertion ) ); 100 } 101 this->type = type; 76 102 } 77 103 -
src/AST/Decl.hpp
rf75e25b re5628db 9 9 // Author : Aaron B. Moss 10 10 // Created On : Thu May 9 10:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Mar 12 18:25:05 202113 // Update Count : 3 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu May 5 12:09:00 2022 13 // Update Count : 33 14 14 // 15 15 … … 135 135 std::vector< ptr<Expr> > withExprs; 136 136 137 // The difference between the two constructors is in how they handle 138 // assertions. The first constructor uses the assertions from the type 139 // parameters, in the style of the old ast, and puts them on the type. 140 // The second takes an explicite list of assertions and builds a list of 141 // references to them on the type. 142 137 143 FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall, 138 144 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 139 145 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 140 146 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false); 141 // : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 142 // stmts( stmts ) {} 147 148 FunctionDecl( const CodeLocation & location, const std::string & name, 149 std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions, 150 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 151 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 152 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, bool isVarArgs = false); 143 153 144 154 const Type * get_type() const override; -
src/AST/Expr.hpp
rf75e25b re5628db 784 784 public: 785 785 ptr<Expr> expr; 786 ptr<ObjectDecl> object;786 readonly<ObjectDecl> object; 787 787 ptr<VariableExpr> var; 788 788 unsigned long long id; -
src/AST/Label.hpp
rf75e25b re5628db 34 34 std::vector< ptr<Attribute> > attributes; 35 35 36 Label( CodeLocationloc, const std::string& name = "",36 Label( const CodeLocation& loc, const std::string& name = "", 37 37 std::vector<ptr<Attribute>> && attrs = std::vector<ptr<Attribute>>{} ) 38 38 : location( loc ), name( name ), attributes( attrs ) {} -
src/AST/Node.hpp
rf75e25b re5628db 10 10 // Created On : Wed May 8 10:27:04 2019 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Mar 25 10:33:00 202213 // Update Count : 712 // Last Modified On : Mon May 9 10:20:00 2022 13 // Update Count : 8 14 14 // 15 15 … … 49 49 50 50 bool unique() const { return strong_count == 1; } 51 bool isManaged() const {return strong_count > 0; } 51 bool isManaged() const { return strong_count > 0; } 52 bool isReferenced() const { return weak_count > 0; } 53 bool isStable() const { 54 return (1 == strong_count || (1 < strong_count && 0 == weak_count)); 55 } 52 56 53 57 private: -
src/AST/Pass.proto.hpp
rf75e25b re5628db 131 131 template< typename node_t > 132 132 struct result1 { 133 bool differs ;134 const node_t * value ;133 bool differs = false; 134 const node_t * value = nullptr; 135 135 136 136 template< typename object_t, typename super_t, typename field_t > … … 151 151 }; 152 152 153 bool differs ;153 bool differs = false; 154 154 container_t< delta > values; 155 155 … … 167 167 template< template<class...> class container_t, typename node_t > 168 168 struct resultN { 169 bool differs ;169 bool differs = false; 170 170 container_t<ptr<node_t>> values; 171 171 -
src/AST/Stmt.cpp
rf75e25b re5628db 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 8 13:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Feb 2 19:01:20 202213 // Update Count : 311 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 3 15:18:20 2022 13 // Update Count : 4 14 14 // 15 15 16 16 #include "Stmt.hpp" 17 17 18 18 #include "Copy.hpp" 19 19 #include "DeclReplacer.hpp" 20 20 #include "Type.hpp" … … 23 23 24 24 // --- CompoundStmt 25 CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids(other.kids) { 25 CompoundStmt::CompoundStmt( const CompoundStmt& other ) : Stmt(other), kids() { 26 // Statements can have weak references to them, if that happens inserting 27 // the original node into the new list will put the original node in a 28 // bad state, where it cannot be mutated. To avoid this, just perform an 29 // additional shallow copy on the statement. 30 for ( const Stmt * kid : other.kids ) { 31 if ( kid->isReferenced() ) { 32 kids.emplace_back( ast::shallowCopy( kid ) ); 33 } else { 34 kids.emplace_back( kid ); 35 } 36 } 37 26 38 // when cloning a compound statement, we may end up cloning declarations which 27 39 // are referred to by VariableExprs throughout the block. Cloning a VariableExpr -
src/AST/Stmt.hpp
rf75e25b re5628db 58 58 // cannot be, they are sub-types of this type, for organization. 59 59 60 StmtClause( const CodeLocation & loc )60 StmtClause( const CodeLocation & loc ) 61 61 : ParseNode(loc) {} 62 62 … … 396 396 class WaitForClause final : public StmtClause { 397 397 public: 398 ptr<Expr> target_func;399 std::vector<ptr<Expr>> target_args;400 ptr<Stmt> stmt;401 ptr<Expr> cond;402 403 WaitForClause( const CodeLocation & loc )398 ptr<Expr> target_func; 399 std::vector<ptr<Expr>> target_args; 400 ptr<Stmt> stmt; 401 ptr<Expr> cond; 402 403 WaitForClause( const CodeLocation & loc ) 404 404 : StmtClause( loc ) {} 405 405 406 406 const WaitForClause * accept( Visitor & v ) const override { return v.visit( this ); } 407 407 private: 408 WaitForClause * clone() const override { return new WaitForClause{ *this }; }409 MUTATE_FRIEND408 WaitForClause * clone() const override { return new WaitForClause{ *this }; } 409 MUTATE_FRIEND 410 410 }; 411 411 -
src/AST/Util.cpp
rf75e25b re5628db 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Util. hpp -- General utilities for working with the AST.7 // Util.cpp -- General utilities for working with the AST. 8 8 // 9 9 // Author : Andrew Beach 10 10 // Created On : Wed Jan 19 9:46:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Mar 11 18:07:00 202213 // Update Count : 112 // Last Modified On : Wed May 11 16:16:00 2022 13 // Update Count : 3 14 14 // 15 15 … … 46 46 47 47 /// Check that every note that can has a set CodeLocation. 48 struct SetCodeLocationsCore { 49 void previsit( const ParseNode * node ) { 50 assert( node->location.isSet() ); 48 void isCodeLocationSet( const ParseNode * node ) { 49 assert( node->location.isSet() ); 50 } 51 52 void areLabelLocationsSet( const Stmt * stmt ) { 53 for ( const Label& label : stmt->labels ) { 54 assert( label.location.isSet() ); 51 55 } 52 }; 56 } 57 58 /// Make sure the reference counts are in a valid combination. 59 void isStable( const Node * node ) { 60 assert( node->isStable() ); 61 } 62 63 /// Check that a FunctionDecl is synchronized with it's FunctionType. 64 void functionDeclMatchesType( const FunctionDecl * decl ) { 65 // The type is a cache of sorts, if it is missing that is only a 66 // problem if isTypeFixed is set. 67 if ( decl->isTypeFixed ) { 68 assert( decl->type ); 69 } else if ( !decl->type ) { 70 return; 71 } 72 73 const FunctionType * type = decl->type; 74 75 // Check that `type->forall` corresponds with `decl->type_params`. 76 assert( type->forall.size() == decl->type_params.size() ); 77 // Check that `type->assertions` corresponds with `decl->assertions`. 78 assert( type->assertions.size() == decl->assertions.size() ); 79 // Check that `type->params` corresponds with `decl->params`. 80 assert( type->params.size() == decl->params.size() ); 81 // Check that `type->returns` corresponds with `decl->returns`. 82 assert( type->returns.size() == decl->returns.size() ); 83 } 53 84 54 85 struct InvariantCore { … … 56 87 // None of the passes should make changes so ordering doesn't matter. 57 88 NoStrongCyclesCore no_strong_cycles; 58 SetCodeLocationsCore set_code_locations;59 89 60 90 void previsit( const Node * node ) { 61 91 no_strong_cycles.previsit( node ); 92 isStable( node ); 62 93 } 63 94 64 95 void previsit( const ParseNode * node ) { 65 no_strong_cycles.previsit( node ); 66 set_code_locations.previsit( node ); 96 previsit( (const Node *)node ); 97 isCodeLocationSet( node ); 98 } 99 100 void previsit( const FunctionDecl * node ) { 101 previsit( (const ParseNode *)node ); 102 functionDeclMatchesType( node ); 103 } 104 105 void previsit( const Stmt * node ) { 106 previsit( (const ParseNode *)node ); 107 areLabelLocationsSet( node ); 67 108 } 68 109 -
src/Common/CodeLocationTools.cpp
rf75e25b re5628db 10 10 // Created On : Fri Dec 4 15:42:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Mar 14 15:14:00 202213 // Update Count : 412 // Last Modified On : Wed May 11 16:16:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 24 24 namespace { 25 25 26 // There are a lot of helpers in this file that could be used much more27 // generally if anyone has another use for them.28 29 // Check if a node type has a code location.30 template<typename node_t>31 struct has_code_location : public std::is_base_of<ast::ParseNode, node_t> {};32 33 template<typename node_t, bool has_location>34 struct __GetCL;35 36 template<typename node_t>37 struct __GetCL<node_t, true> {38 static inline CodeLocation const * get( node_t const * node ) {39 return &node->location;40 }41 42 static inline CodeLocation * get( node_t * node ) {43 return &node->location;44 }45 };46 47 template<typename node_t>48 struct __GetCL<node_t, false> {49 static inline CodeLocation * get( node_t const * ) {50 return nullptr;51 }52 };53 54 template<typename node_t>55 CodeLocation const * get_code_location( node_t const * node ) {56 return __GetCL< node_t, has_code_location< node_t >::value >::get( node );57 }58 59 template<typename node_t>60 CodeLocation * get_code_location( node_t * node ) {61 return __GetCL< node_t, has_code_location< node_t >::value >::get( node );62 }63 64 26 // Fill every location with a nearby (parent) location. 65 27 class FillCore : public ast::WithGuards { 66 28 CodeLocation const * parent; 29 30 template<typename node_t> 31 node_t const * parse_visit( node_t const * node ) { 32 if ( node->location.isUnset() ) { 33 assert( parent ); 34 node_t * newNode = ast::mutate( node ); 35 newNode->location = *parent; 36 return newNode; 37 } 38 GuardValue( parent ) = &node->location; 39 return node; 40 } 41 42 bool hasUnsetLabels( const ast::Stmt * stmt ) { 43 for ( const ast::Label& label : stmt->labels ) { 44 if ( label.location.isUnset() ) { 45 return true; 46 } 47 } 48 return false; 49 } 50 51 template<typename node_t> 52 node_t const * stmt_visit( node_t const * node ) { 53 assert( node->location.isSet() ); 54 55 if ( hasUnsetLabels( node ) ) { 56 node_t * newNode = ast::mutate( node ); 57 for ( ast::Label& label : newNode->labels ) { 58 if ( label.location.isUnset() ) { 59 label.location = newNode->location; 60 } 61 } 62 return newNode; 63 } 64 return node; 65 } 66 67 template<typename node_t> 68 auto visit( node_t const * node, long ) { 69 return node; 70 } 71 72 template<typename node_t> 73 auto visit( node_t const * node, int ) -> typename 74 std::remove_reference< decltype( node->location, node ) >::type { 75 return parse_visit( node ); 76 } 77 78 template<typename node_t> 79 auto visit( node_t const * node, char ) -> typename 80 std::remove_reference< decltype( node->labels, node ) >::type { 81 return stmt_visit( parse_visit( node ) ); 82 } 83 67 84 public: 68 85 FillCore() : parent( nullptr ) {} 86 FillCore( const CodeLocation& location ) : parent( &location ) { 87 assert( location.isSet() ); 88 } 69 89 70 90 template<typename node_t> 71 91 node_t const * previsit( node_t const * node ) { 72 GuardValue( parent ); 73 CodeLocation const * location = get_code_location( node ); 74 if ( location && location->isUnset() ) { 75 assert( parent ); 76 node_t * newNode = ast::mutate( node ); 77 CodeLocation * newLocation = get_code_location( newNode ); 78 assert( newLocation ); 79 *newLocation = *parent; 80 parent = newLocation; 81 return newNode; 82 } else if ( location ) { 83 parent = location; 84 } 85 return node; 92 return visit( node, '\0' ); 86 93 } 87 94 }; … … 233 240 234 241 template<typename node_t> 235 void previsit( node_t const * node ) { 236 CodeLocation const * location = get_code_location( node ); 237 if ( location && location->isUnset() ) { 242 auto previsit( node_t const * node ) -> decltype( node->location, void() ) { 243 if ( node->location.isUnset() ) { 238 244 unset.push_back( node ); 239 }240 }241 };242 243 class LocalFillCore : public ast::WithGuards {244 CodeLocation const * parent;245 public:246 LocalFillCore( CodeLocation const & location ) : parent( &location ) {247 assert( location.isSet() );248 }249 250 template<typename node_t>251 auto previsit( node_t const * node )252 -> typename std::enable_if<has_code_location<node_t>::value, node_t const *>::type {253 if ( node->location.isSet() ) {254 GuardValue( parent ) = &node->location;255 return node;256 } else {257 node_t * mut = ast::mutate( node );258 mut->location = *parent;259 return mut;260 245 } 261 246 } … … 304 289 ast::Node const * localFillCodeLocations( 305 290 CodeLocation const & location , ast::Node const * node ) { 306 ast::Pass< LocalFillCore> visitor( location );291 ast::Pass<FillCore> visitor( location ); 307 292 return node->accept( visitor ); 308 293 } -
src/ControlStruct/LabelGeneratorNew.hpp
rf75e25b re5628db 18 18 #include <string> // for string 19 19 20 classCodeLocation;20 struct CodeLocation; 21 21 22 22 namespace ast { -
src/ControlStruct/MultiLevelExit.cpp
rf75e25b re5628db 18 18 #include "AST/Pass.hpp" 19 19 #include "AST/Stmt.hpp" 20 #include "Common/CodeLocationTools.hpp" 20 21 #include "LabelGeneratorNew.hpp" 21 22 … … 228 229 // Labels on different stmts require different approaches to access 229 230 switch ( stmt->kind ) { 230 case BranchStmt::Goto:231 case BranchStmt::Goto: 231 232 return stmt; 232 case BranchStmt::Continue:233 case BranchStmt::Break: {234 bool isContinue = stmt->kind == BranchStmt::Continue;235 // Handle unlabeled break and continue.236 if ( stmt->target.empty() ) {237 if ( isContinue ) {238 targetEntry = findEnclosingControlStructure( isContinueTarget );239 } else {240 if ( enclosing_control_structures.empty() ) {233 case BranchStmt::Continue: 234 case BranchStmt::Break: { 235 bool isContinue = stmt->kind == BranchStmt::Continue; 236 // Handle unlabeled break and continue. 237 if ( stmt->target.empty() ) { 238 if ( isContinue ) { 239 targetEntry = findEnclosingControlStructure( isContinueTarget ); 240 } else { 241 if ( enclosing_control_structures.empty() ) { 241 242 SemanticError( stmt->location, 242 243 "'break' outside a loop, 'switch', or labelled block" ); 243 }244 targetEntry = findEnclosingControlStructure( isBreakTarget );245 }246 // Handle labeled break and continue.247 } else {248 // Lookup label in table to find attached control structure.249 targetEntry = findEnclosingControlStructure(250 [ targetStmt = target_table.at(stmt->target) ](auto entry){244 } 245 targetEntry = findEnclosingControlStructure( isBreakTarget ); 246 } 247 // Handle labeled break and continue. 248 } else { 249 // Lookup label in table to find attached control structure. 250 targetEntry = findEnclosingControlStructure( 251 [ targetStmt = target_table.at(stmt->target) ](auto entry){ 251 252 return entry.stmt == targetStmt; 252 } );253 }254 // Ensure that selected target is valid.255 if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {256 SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),253 } ); 254 } 255 // Ensure that selected target is valid. 256 if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) { 257 SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"), 257 258 " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), 258 259 stmt->originalTarget ) ); 259 }260 break;261 }262 // handle fallthrough in case/switch stmts263 case BranchStmt::FallThrough: {264 targetEntry = findEnclosingControlStructure( isFallthroughTarget );265 // Check that target is valid.266 if ( targetEntry == enclosing_control_structures.rend() ) {267 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );268 }269 if ( ! stmt->target.empty() ) {270 // Labelled fallthrough: target must be a valid fallthough label.271 if ( ! fallthrough_labels.count( stmt->target ) ) {272 SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ",260 } 261 break; 262 } 263 // handle fallthrough in case/switch stmts 264 case BranchStmt::FallThrough: { 265 targetEntry = findEnclosingControlStructure( isFallthroughTarget ); 266 // Check that target is valid. 267 if ( targetEntry == enclosing_control_structures.rend() ) { 268 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" ); 269 } 270 if ( ! stmt->target.empty() ) { 271 // Labelled fallthrough: target must be a valid fallthough label. 272 if ( ! fallthrough_labels.count( stmt->target ) ) { 273 SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ", 273 274 stmt->originalTarget ) ); 274 }275 return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget );276 }277 break;278 }279 case BranchStmt::FallThroughDefault: {280 targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );281 282 // Check if in switch or choose statement.283 if ( targetEntry == enclosing_control_structures.rend() ) {284 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );285 }286 287 // Check if switch or choose has default clause.288 auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );289 bool foundDefault = false;290 for ( auto caseStmt : switchStmt->cases ) {291 if ( caseStmt->isDefault() ) {292 foundDefault = true;293 break;294 }295 }296 if ( ! foundDefault ) {297 SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"298 "control structure with a 'default' clause" );299 }300 break;301 }302 default:275 } 276 return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget ); 277 } 278 break; 279 } 280 case BranchStmt::FallThroughDefault: { 281 targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget ); 282 283 // Check if in switch or choose statement. 284 if ( targetEntry == enclosing_control_structures.rend() ) { 285 SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" ); 286 } 287 288 // Check if switch or choose has default clause. 289 auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt ); 290 bool foundDefault = false; 291 for ( auto caseStmt : switchStmt->cases ) { 292 if ( caseStmt->isDefault() ) { 293 foundDefault = true; 294 break; 295 } 296 } 297 if ( ! foundDefault ) { 298 SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'" 299 "control structure with a 'default' clause" ); 300 } 301 break; 302 } 303 default: 303 304 assert( false ); 304 305 } … … 307 308 Label exitLabel( CodeLocation(), "" ); 308 309 switch ( stmt->kind ) { 309 case BranchStmt::Break:310 case BranchStmt::Break: 310 311 assert( ! targetEntry->useBreakExit().empty() ); 311 312 exitLabel = targetEntry->useBreakExit(); 312 313 break; 313 case BranchStmt::Continue:314 case BranchStmt::Continue: 314 315 assert( ! targetEntry->useContExit().empty() ); 315 316 exitLabel = targetEntry->useContExit(); 316 317 break; 317 case BranchStmt::FallThrough:318 case BranchStmt::FallThrough: 318 319 assert( ! targetEntry->useFallExit().empty() ); 319 320 exitLabel = targetEntry->useFallExit(); 320 321 break; 321 case BranchStmt::FallThroughDefault:322 case BranchStmt::FallThroughDefault: 322 323 assert( ! targetEntry->useFallDefaultExit().empty() ); 323 324 exitLabel = targetEntry->useFallDefaultExit(); … … 327 328 } 328 329 break; 329 default:330 default: 330 331 assert(0); 331 332 } … … 633 634 Pass<MultiLevelExitCore> visitor( labelTable ); 634 635 const CompoundStmt * ret = stmt->accept( visitor ); 635 return ret; 636 // There are some unset code locations slipping in, possibly by Labels. 637 const Node * node = localFillCodeLocations( ret->location, ret ); 638 return strict_dynamic_cast<const CompoundStmt *>( node ); 636 639 } 637 640 } // namespace ControlStruct -
src/Parser/parser.yy
rf75e25b re5628db 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 4 1 4:25:20202213 // Update Count : 527 712 // Last Modified On : Wed May 4 17:22:48 2022 13 // Update Count : 5279 14 14 // 15 15 … … 1224 1224 { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); } 1225 1225 | WHILE '(' ')' statement ELSE statement // CFA 1226 { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); SemanticWarning( yylloc, Warning::SuperfluousElse ); } 1226 { 1227 $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); 1228 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1229 } 1227 1230 | WHILE '(' conditional_declaration ')' statement %prec THEN 1228 1231 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); } … … 1232 1235 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); } 1233 1236 | DO statement WHILE '(' ')' ELSE statement // CFA 1234 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); SemanticWarning( yylloc, Warning::SuperfluousElse ); } 1235 | DO statement WHILE '(' comma_expression ')' ';' %prec THEN 1237 { 1238 $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); 1239 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1240 } 1241 | DO statement WHILE '(' comma_expression ')' ';' 1236 1242 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); } 1237 1243 | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA 1238 1244 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); } 1239 | FOR '(' ')' statement // CFA => for ( ;; )1245 | FOR '(' ')' statement %prec THEN // CFA => for ( ;; ) 1240 1246 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); } 1241 | FOR '(' ')' statement ELSE statement // CFA 1242 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); SemanticWarning( yylloc, Warning::SuperfluousElse ); } 1247 | FOR '(' ')' statement ELSE statement // CFA 1248 { 1249 $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); 1250 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1251 } 1243 1252 | FOR '(' for_control_expression_list ')' statement %prec THEN 1244 1253 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); } -
src/Validate/Autogen.cpp
rf75e25b re5628db 350 350 name, 351 351 std::move( type_params ), 352 std::move( assertions ), 352 353 std::move( params ), 353 354 std::move( returns ), … … 360 361 // Auto-generated routines are inline to avoid conflicts. 361 362 ast::Function::Specs( ast::Function::Inline ) ); 362 decl->assertions = std::move( assertions );363 363 decl->fixUniqueId(); 364 364 return decl;
Note:
See TracChangeset
for help on using the changeset viewer.