Changeset 7675f58


Ignore:
Timestamp:
May 11, 2022, 4:22:38 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
491bb81
Parents:
3f681b1
Message:

Labels on statements (not all Labels in the AST) now have all their locations filled.

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Util.cpp

    r3f681b1 r7675f58  
    1010// Created On       : Wed Jan 19  9:46:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed May  4 15:50:00 2022
    13 // Update Count     : 2
     12// Last Modified On : Wed May 11 16:16:00 2022
     13// Update Count     : 3
    1414//
    1515
     
    4848void isCodeLocationSet( const ParseNode * node ) {
    4949        assert( node->location.isSet() );
     50}
     51
     52void areLabelLocationsSet( const Stmt * stmt ) {
     53        for ( const Label& label : stmt->labels ) {
     54                assert( label.location.isSet() );
     55        }
    5056}
    5157
     
    97103        }
    98104
     105        void previsit( const Stmt * node ) {
     106                previsit( (const ParseNode *)node );
     107                areLabelLocationsSet( node );
     108        }
     109
    99110        void postvisit( const Node * node ) {
    100111                no_strong_cycles.postvisit( node );
  • src/Common/CodeLocationTools.cpp

    r3f681b1 r7675f58  
    1010// Created On       : Fri Dec  4 15:42:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Mar 14 15:14:00 2022
    13 // Update Count     : 4
     12// Last Modified On : Wed May 11 16:16:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    2424namespace {
    2525
    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 
    6426// Fill every location with a nearby (parent) location.
    6527class FillCore : public ast::WithGuards {
    6628        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
    6784public:
    6885        FillCore() : parent( nullptr ) {}
     86        FillCore( const CodeLocation& location ) : parent( &location ) {
     87                assert( location.isSet() );
     88        }
    6989
    7090        template<typename node_t>
    7191        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' );
    8693        }
    8794};
     
    233240
    234241        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() ) {
    238244                        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;
    260245                }
    261246        }
     
    304289ast::Node const * localFillCodeLocations(
    305290                CodeLocation const & location , ast::Node const * node ) {
    306         ast::Pass<LocalFillCore> visitor( location );
     291        ast::Pass<FillCore> visitor( location );
    307292        return node->accept( visitor );
    308293}
Note: See TracChangeset for help on using the changeset viewer.