Changeset 7675f58
- Timestamp:
- May 11, 2022, 4:22:38 PM (2 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
- Children:
- 491bb81
- Parents:
- 3f681b1
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Util.cpp
r3f681b1 r7675f58 10 10 // Created On : Wed Jan 19 9:46:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 4 15:50:00 202213 // Update Count : 212 // Last Modified On : Wed May 11 16:16:00 2022 13 // Update Count : 3 14 14 // 15 15 … … 48 48 void isCodeLocationSet( const ParseNode * node ) { 49 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() ); 55 } 50 56 } 51 57 … … 97 103 } 98 104 105 void previsit( const Stmt * node ) { 106 previsit( (const ParseNode *)node ); 107 areLabelLocationsSet( node ); 108 } 109 99 110 void postvisit( const Node * node ) { 100 111 no_strong_cycles.postvisit( node ); -
src/Common/CodeLocationTools.cpp
r3f681b1 r7675f58 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 }
Note: See TracChangeset
for help on using the changeset viewer.