source: src/Common/CodeLocationTools.cpp @ c9e0991

arm-ehenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-expr
Last change on this file since c9e0991 was c9e0991, checked in by Andrew Beach <ajbeach@…>, 18 months ago

Clean-up the code location tools.

  • Property mode set to 100644
File size: 3.0 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// CodeLocationTools.cpp -- Additional tools for code locations.
8//
9// Author           : Andrew Beach
10// Created On       : Fri Dec  4 15:42:00 2020
11// Last Modified By : Andrew Beach
12// Last Modified On : Mon Dec  7 15:15:00 2020
13// Update Count     : 0
14//
15
16#include "CodeLocationTools.hpp"
17
18#include <type_traits>
19
20#include "AST/Pass.hpp"
21#include "AST/TranslationUnit.hpp"
22#include "Common/CodeLocation.h"
23
24namespace {
25
26template<typename node_t>
27struct has_code_location : public std::is_base_of<ast::ParseNode, node_t> {};
28
29template<typename node_t, bool has_location>
30struct __GetCL;
31
32template<typename node_t>
33struct __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 ) {
39                return &node->location;
40        }
41};
42
43template<typename node_t>
44struct __GetCL<node_t, false> {
45        static inline CodeLocation * get( node_t const * ) {
46                return nullptr;
47        }
48};
49
50template<typename node_t>
51CodeLocation const * get_code_location( node_t const * node ) {
52        return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
53}
54
55template<typename node_t>
56CodeLocation * 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.
61class FillCore : public ast::WithGuards {
62        CodeLocation const * parent;
63public:
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};
84
85// Collect pointers to all the nodes with unset code locations.
86class CollectCore {
87        std::list< ast::ptr< ast::Node > > & unset;
88public:
89        CollectCore( std::list< ast::ptr< ast::Node > > & unset ) :
90                unset( unset )
91        {}
92
93        template<typename node_t>
94        void previsit( node_t const * node ) {
95                CodeLocation const * location = get_code_location( node );
96                if ( location && location->isUnset() ) {
97                        unset.push_back( node );
98                }
99        }
100};
101
102} // namespace
103
104void checkAllCodeLocations( ast::TranslationUnit const & unit ) {
105        std::list< ast::ptr< ast::Node > > unsetNodes;
106        {
107                ast::Pass<CollectCore> collector( unsetNodes );
108                for ( auto node : unit.decls ) {
109                        node->accept( collector );
110                }
111        }
112        if ( unsetNodes.empty() ) {
113                return;
114        }
115
116        std::cerr << "Total nodes without a set code location: "
117                << unsetNodes.size() << std::endl;
118
119        assert( unsetNodes.empty() );
120}
121
122void forceFillCodeLocations( ast::TranslationUnit & unit ) {
123        ast::Pass<FillCore>::run( unit );
124}
Note: See TracBrowser for help on using the repository browser.