- File:
-
- 1 edited
-
src/Common/CodeLocationTools.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Common/CodeLocationTools.cpp
r7675f58 rf6e6a55 10 10 // Created On : Fri Dec 4 15:42:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed May 11 16:16:00 202213 // Update Count : 512 // Last Modified On : Mon Mar 14 15:14:00 2022 13 // Update Count : 4 14 14 // 15 15 … … 24 24 namespace { 25 25 26 // There are a lot of helpers in this file that could be used much more 27 // 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 26 64 // Fill every location with a nearby (parent) location. 27 65 class FillCore : public ast::WithGuards { 28 66 CodeLocation const * parent; 67 public: 68 FillCore() : parent( nullptr ) {} 29 69 30 70 template<typename node_t> 31 node_t const * parse_visit( node_t const * node ) { 32 if ( node->location.isUnset() ) { 71 node_t const * previsit( node_t const * node ) { 72 GuardValue( parent ); 73 CodeLocation const * location = get_code_location( node ); 74 if ( location && location->isUnset() ) { 33 75 assert( parent ); 34 76 node_t * newNode = ast::mutate( node ); 35 newNode->location = *parent; 77 CodeLocation * newLocation = get_code_location( newNode ); 78 assert( newLocation ); 79 *newLocation = *parent; 80 parent = newLocation; 36 81 return newNode; 37 } 38 GuardValue( parent ) = &node->location; 82 } else if ( location ) { 83 parent = location; 84 } 39 85 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 ) -> typename74 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 ) -> typename80 std::remove_reference< decltype( node->labels, node ) >::type {81 return stmt_visit( parse_visit( node ) );82 }83 84 public:85 FillCore() : parent( nullptr ) {}86 FillCore( const CodeLocation& location ) : parent( &location ) {87 assert( location.isSet() );88 }89 90 template<typename node_t>91 node_t const * previsit( node_t const * node ) {92 return visit( node, '\0' );93 86 } 94 87 }; … … 240 233 241 234 template<typename node_t> 242 auto previsit( node_t const * node ) -> decltype( node->location, void() ) { 243 if ( node->location.isUnset() ) { 235 void previsit( node_t const * node ) { 236 CodeLocation const * location = get_code_location( node ); 237 if ( location && location->isUnset() ) { 244 238 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; 245 260 } 246 261 } … … 289 304 ast::Node const * localFillCodeLocations( 290 305 CodeLocation const & location , ast::Node const * node ) { 291 ast::Pass< FillCore> visitor( location );306 ast::Pass<LocalFillCore> visitor( location ); 292 307 return node->accept( visitor ); 293 308 }
Note:
See TracChangeset
for help on using the changeset viewer.