source: src/ArgTweak/FunctionFixer.cc @ dae881f

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since dae881f was f1b1e4c, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

can construct global const objects, except with intrinsic constructors

  • Property mode set to 100644
File size: 4.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// FunctionFixer.cc --
8//
9// Author           : Rodolfo G. Esteves
10// Created On       : Sat May 16 08:12:38 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu May 21 21:11:45 2015
13// Update Count     : 7
14//
15
16#include <list>
17#include <vector>
18#include <cassert>
19#include <algorithm>
20
21#include "FunctionFixer.h"
22#include "SynTree/Expression.h"
23#include "SynTree/Declaration.h"
24#include "SynTree/Type.h"
25
26namespace ArgTweak {
27        FunctionFixer::FunctionFixer( SymTab::Indexer *ind ) : index( ind ) {
28                if ( index == 0 ) index = new SymTab::Indexer();
29        }
30
31        FunctionFixer::~FunctionFixer() {
32                delete index;
33        }
34
35        DeclarationWithType *FunctionFixer::mutate( FunctionDecl *functionDecl ) {
36                index->visit( functionDecl );
37                /* check for duplicate named parameters here?  It might not be an error if they're never used, on the other hand, it
38                   might be to costly to check for duplicates every time we try a match */
39                return Parent::mutate( functionDecl );
40        }
41
42        Expression *FunctionFixer::mutate( UntypedExpr *untypedExpr ) throw ( SemanticError ) {
43                assert( untypedExpr != 0 );
44
45                if ( NameExpr * function = dynamic_cast< NameExpr *>(untypedExpr->get_function() ) ) {
46                        std::list < DeclarationWithType * > options;
47                        index->lookupId ( function->get_name(), options );
48                        for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) {
49                                if ( FunctionType * f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) )   {
50                                        std::list < DeclarationWithType * > &pars = f->get_parameters();
51                                        bool candidateExists ;
52                                        for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ ) {
53                                                if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
54                                        }
55                                        if ( ! candidateExists ) throw SemanticError("Error in function call");
56                                } // if
57                        } // for
58                } // if
59                return untypedExpr;
60        }
61
62        template < class L1, class L2, class Helper >
63        bool align( L1 &pattern, L2 &possible_permutation, Helper help ) {
64                std::map < typename Helper::key, int > positions;
65                int p = 0;
66
67                for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ )
68                        if ( help.extract_key( *i ) != Helper::null_key )
69                                positions[ help.extract_key( *i ) ] = p;
70
71                L2 copy_pp( possible_permutation );
72
73                std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value );
74                for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ )
75                        if ( positions.find( help.extract_key( *i ) ) != positions.end() ) {
76                                temp [ positions [ help.extract_key( *i ) ] ] = *i;
77                                *i = Helper::null_value;
78                        } // if
79
80                // rest of the arguments
81                int a = 0;
82                bool goAhead = true;                                                    // go ahead and change the list
83                for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) {
84                        if (  *i != Helper::null_value )
85                                if ( temp[a] == Helper::null_value )
86                                        temp[a] = *i;
87                                else
88                                        { goAhead = false; /* there's something there already */; break; }
89                        else
90                                if ( temp[a] == Helper::null_value )
91                                        { goAhead = false; /* can't leave empty spaces */ break; }
92                                else
93                                        ;                                                                       // all good, this was filled during the first pass
94                        assert ( temp[a] != Helper::null_value );
95                } // for
96
97                // Change the original list
98                if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
99
100                return goAhead;
101        }
102
103        std::string FunctionFixer::Matcher::null_key("");
104        Expression *FunctionFixer::Matcher::null_value = 0;
105
106        std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) {
107                return decl->get_name();
108        }
109
110        std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) {
111                if ( expression->get_argName() == 0 )
112                        return std::string("");
113                else
114                        return *(expression->get_argName());
115        }
116} // namespace ArgTweak
117
118// Local Variables: //
119// tab-width: 4 //
120// mode: c++ //
121// compile-command: "make install" //
122// End: //
Note: See TracBrowser for help on using the repository browser.