source: src/ArgTweak/FunctionFixer.cc @ 59cde21

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 59cde21 was 843054c2, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: seventh groups of files

  • Property mode set to 100644
File size: 4.1 KB
RevLine 
[b87a5ed]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//
[843054c2]9// Author           : Rodolfo G. Esteves
[b87a5ed]10// Created On       : Sat May 16 08:12:38 2015
11// Last Modified By : Peter A. Buhr
[843054c2]12// Last Modified On : Thu May 21 21:11:45 2015
13// Update Count     : 7
[b87a5ed]14//
15
[51b7345]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 {
[b87a5ed]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                NameExpr *function;
45
46                if ( ( function = dynamic_cast< NameExpr *>(untypedExpr->get_function()) ) != 0 ) {
47                        std::list < DeclarationWithType * > options;
48                        index->lookupId ( function->get_name(), options );
49                        for ( std::list < DeclarationWithType * >::iterator i = options.begin(); i != options.end(); i++ ) {
50                                FunctionType *f;
51                                if ( ( f = dynamic_cast< FunctionType * > ( (*i)->get_type() ) ) != 0 ) {
52                                        std::list < DeclarationWithType * > &pars = f->get_parameters();
53
54                                        bool candidateExists ;
55                                        for ( std::list < DeclarationWithType * >::iterator p = pars.begin(); p != pars.end(); p++ )
56                                                if ( ( candidateExists = align( f->get_parameters(), untypedExpr->get_args(), Matcher() ) ) ) break;
57
[a32b204]58                                        if ( ! candidateExists ) throw SemanticError("Error in function call");
[b87a5ed]59                                } // if
60                        } // for
61                } // if
62                return untypedExpr;
63        }
64
65        template < class L1, class L2, class Helper >
66        bool align( L1 &pattern, L2 &possible_permutation, Helper help ) {
67                std::map < typename Helper::key, int > positions;
68                int p = 0;
69
70                for ( typename L1::iterator i = pattern.begin(); i != pattern.end(); i++, p++ )
71                        if ( help.extract_key( *i ) != Helper::null_key )
72                                positions[ help.extract_key( *i ) ] = p;
73
74                L2 copy_pp( possible_permutation );
75
76                std::vector< typename L2::value_type > temp(copy_pp.size(), Helper::null_value );
77                for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++ )
78                        if ( positions.find( help.extract_key( *i ) ) != positions.end() ) {
79                                temp [ positions [ help.extract_key( *i ) ] ] = *i;
80                                *i = Helper::null_value;
81                        } // if
82
83                // rest of the arguments
84                int a = 0;
85                bool goAhead = true;                                                    // go ahead and change the list
86                for ( typename L2::iterator i = copy_pp.begin(); i != copy_pp.end(); i++, a++ ) {
87                        if (  *i != Helper::null_value )
88                                if ( temp[a] == Helper::null_value )
89                                        temp[a] = *i;
90                                else
91                                        { goAhead = false; /* there's something there already */; break; }
92                        else
93                                if ( temp[a] == Helper::null_value )
94                                        { goAhead = false; /* can't leave empty spaces */ break; }
95                                else
96                                        ;                                                                       // all good, this was filled during the first pass
97                        assert ( temp[a] != Helper::null_value );
98                } // for
99
100                // Change the original list
101                if ( goAhead ) std::copy( temp.begin(), temp.end(), possible_permutation.begin() );
102
103                return goAhead;
104        }
105
106        std::string FunctionFixer::Matcher::null_key("");
107        Expression *FunctionFixer::Matcher::null_value = 0;
108
109        std::string FunctionFixer::Matcher::extract_key ( DeclarationWithType *decl ) {
110                return decl->get_name();
111        }
112
113        std::string FunctionFixer::Matcher::extract_key ( Expression *expression ) {
114                if ( expression->get_argName() == 0 )
115                        return std::string("");
116                else
117                        return *(expression->get_argName());
118        }
[51b7345]119} // namespace ArgTweak
[b87a5ed]120
121// Local Variables: //
122// tab-width: 4 //
123// mode: c++ //
124// compile-command: "make install" //
125// End: //
Note: See TracBrowser for help on using the repository browser.