source: src/Common/CodeLocationTools.cpp @ f57faf6f

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since f57faf6f was f57faf6f, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Added a new-ast tools for code locations. The fill pass is being used the check pass is catching lots of missing locations when you enable it.

  • Property mode set to 100644
File size: 3.3 KB
RevLine 
[f57faf6f]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
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
71template<typename node_t, bool has_location>
72struct __GetCL;
73
74template<typename node_t>
75struct __GetCL<node_t, true> {
76        static CodeLocation const * get( node_t const * node ) {
77                return &node->location;
78        }
79};
80
81template<typename node_t>
82struct __GetCL<node_t, false> {
83        static CodeLocation const * get( node_t const * ) {
84                return nullptr;
85        }
86};
87
88template<typename node_t>
89CodeLocation const * get_code_location( node_t const * node ) {
90        return __GetCL< node_t, has_code_location< node_t >::value >::get( node );
91}
92
93// Collect pointers to all the nodes with unset code locations.
94class CollectCore {
95        std::list< ast::ptr< ast::Node > > & unset;
96public:
97        CollectCore( std::list< ast::ptr< ast::Node > > & unset ) :
98                unset( unset )
99        {}
100
101        template<typename node_t>
102        void previsit( node_t const * node ) {
103                CodeLocation const * location = get_code_location( node );
104                if ( location && location->isUnset() ) {
105                        unset.push_back( node );
106                }
107        }
108};
109
110} // namespace
111
112void checkAllCodeLocations( ast::TranslationUnit const & unit ) {
113        std::list< ast::ptr< ast::Node > > unsetNodes;
114        {
115                ast::Pass<CollectCore> collector( unsetNodes );
116                for ( auto node : unit.decls ) {
117                        node->accept( collector );
118                }
119        }
120        if ( unsetNodes.empty() ) {
121                return;
122        }
123
124        std::cerr << "Total nodes without a set code location: "
125                << unsetNodes.size() << std::endl;
126
127        assert( unsetNodes.empty() );
128}
129
130void forceFillCodeLocations( ast::TranslationUnit & unit ) {
131        ast::Pass<FillCore>::run( unit );
132}
Note: See TracBrowser for help on using the repository browser.