Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Common/CodeLocationTools.cpp

    rc9e0991 rf57faf6f  
    2727struct has_code_location : public std::is_base_of<ast::ParseNode, node_t> {};
    2828
     29// Fill every location
     30class FillCore : public ast::WithGuards {
     31        CodeLocation const * parent;
     32
     33        // This mimics a partially specialized method.
     34        template<typename node_t, bool has_location>
     35        struct FillNode;
     36        template<typename node_t, bool has_location>
     37        friend struct FillNode;
     38
     39        template<typename node_t>
     40        struct FillNode<node_t, true> {
     41                static node_t const * go( FillCore * core, node_t const * node ) {
     42                        node_t * newNode = nullptr;
     43                        if ( node->location.isUnset() ) {
     44                                // Just hoping that top level nodes are always marked.
     45                                assert( core->parent );
     46                                newNode = ast::mutate( node );
     47                                newNode->location = *core->parent;
     48                        }
     49                        core->GuardValue( core->parent );
     50                        core->parent = &node->location;
     51                        return (newNode) ? newNode : node;
     52                }
     53        };
     54
     55        template<typename node_t>
     56        struct FillNode<node_t, false> {
     57                static node_t const * go( FillCore *, node_t const * node ) {
     58                        return node;
     59                }
     60        };
     61public:
     62        FillCore() : parent( nullptr ) {}
     63
     64        template<typename node_t>
     65        node_t const * previsit( node_t const * node ) {
     66                using Filler = FillNode<node_t, has_code_location<node_t>::value>;
     67                return Filler::go( this, node );
     68        }
     69};
     70
    2971template<typename node_t, bool has_location>
    3072struct __GetCL;
     
    3274template<typename node_t>
    3375struct __GetCL<node_t, true> {
    34         static inline CodeLocation const * get( node_t const * node ) {
    35                 return &node->location;
    36         }
    37 
    38         static inline CodeLocation * get( node_t * node ) {
     76        static CodeLocation const * get( node_t const * node ) {
    3977                return &node->location;
    4078        }
     
    4381template<typename node_t>
    4482struct __GetCL<node_t, false> {
    45         static inline CodeLocation * get( node_t const * ) {
     83        static CodeLocation const * get( node_t const * ) {
    4684                return nullptr;
    4785        }
     
    5290        return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
    5391}
    54 
    55 template<typename node_t>
    56 CodeLocation * get_code_location( node_t * node ) {
    57         return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
    58 }
    59 
    60 // Fill every location with a nearby (parent) location.
    61 class FillCore : public ast::WithGuards {
    62         CodeLocation const * parent;
    63 public:
    64         FillCore() : parent( nullptr ) {}
    65 
    66         template<typename node_t>
    67         node_t const * previsit( node_t const * node ) {
    68                 GuardValue( parent );
    69                 CodeLocation const * location = get_code_location( node );
    70                 if ( location && location->isUnset() ) {
    71                         assert( parent );
    72                         node_t * newNode = ast::mutate( node );
    73                         CodeLocation * newLocation = get_code_location( newNode );
    74                         assert( newLocation );
    75                         *newLocation = *parent;
    76                         parent = newLocation;
    77                         return newNode;
    78                 } else if ( location ) {
    79                         parent = location;
    80                 }
    81                 return node;
    82         }
    83 };
    8492
    8593// Collect pointers to all the nodes with unset code locations.
Note: See TracChangeset for help on using the changeset viewer.