source: translator/GenPoly/CopyParams.cc @ 0dd3a2f

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 0dd3a2f was a32b204, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: second groups of files

  • Property mode set to 100644
File size: 3.4 KB
Line 
1#include <set>
2#include <map>
3#include <cassert>
4
5#include "SynTree/Declaration.h"
6#include "SynTree/Type.h"
7#include "SynTree/Expression.h"
8#include "SynTree/Statement.h"
9#include "SynTree/Visitor.h"
10#include "UniqueName.h"
11
12
13namespace GenPoly {
14    class CopyParams : public Visitor {
15      public:
16        CopyParams();
17 
18        virtual void visit( FunctionDecl *funcDecl );
19        virtual void visit( AddressExpr *addrExpr );
20
21      private:
22        std::set< UniqueId > modVars;
23        UniqueName namer;
24    };
25
26    void copyParams( std::list< Declaration* > &translationUnit ) {
27        CopyParams copier;
28        acceptAll( translationUnit, copier );
29    }
30
31    CopyParams::CopyParams() : namer( "_cp" ) {}
32
33    static const std::list< Label > noLabels;
34
35    void CopyParams::visit( FunctionDecl *funcDecl ) {
36        if ( funcDecl->get_statements() ) {
37            funcDecl->get_statements()->accept( *this );
38   
39            if ( ! modVars.empty() ) {
40                std::map< std::string, DeclarationWithType* > assignOps;
41                // assume the assignment operator is the first assert param after any "type" parameter
42                for ( std::list< TypeDecl* >::const_iterator tyVar = funcDecl->get_functionType()->get_forall().begin(); tyVar != funcDecl->get_functionType()->get_forall().end(); ++tyVar ) {
43                    if ( (*tyVar)->get_kind() == TypeDecl::Any ) {
44                        assert( !(*tyVar)->get_assertions().empty() );
45                        assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front();
46                    } // if
47                } // for
48                for ( std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
49                    std::set< UniqueId >::const_iterator var = modVars.find( (*param)->get_uniqueId() );
50                    if ( var != modVars.end() ) {
51                        TypeInstType *typeInst = dynamic_cast< TypeInstType* >( (*param)->get_type() );
52                        assert( typeInst );
53                        std::map< std::string, DeclarationWithType* >::const_iterator assignOp = assignOps.find( typeInst->get_name() );
54                        if ( assignOp != assignOps.end() ) {
55                            DeclarationWithType *oldParam = *param;
56                            *param = (*param)->clone();
57                            (*param)->set_mangleName( namer.newName( (*param)->get_mangleName() ) );
58                            ApplicationExpr *assign = new ApplicationExpr( new VariableExpr( assignOp->second ) );
59                            assign->get_args().push_back( new VariableExpr( oldParam ) );
60                            assign->get_args().push_back( new VariableExpr( *param ) );
61                            funcDecl->get_statements()->get_kids().push_front( new ExprStmt( noLabels, assign ) );
62                            funcDecl->get_statements()->get_kids().push_front( new DeclStmt( noLabels, oldParam ) );
63                        } // if
64                        modVars.erase( var );
65                    } // if
66                } // for
67            } // if
68        } // if
69    }
70
71    // this test is insufficient because it is possible for values to be modified by being passed to other polymorphic
72    // routines (e.g., assignment operators) without having their addresses explicitly taken. Some thought is needed to
73    // make sure that all of the correct cases are identified where copies are necessary.
74    //
75    // As a temporary measure, for correctness at the expense of performance, ignore the modVars list entirely and copy
76    // every parameter of TypeInstType* when visiting the FunctionDecl.
77    void CopyParams::visit( AddressExpr *addrExpr ) {
78        if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( addrExpr->get_arg() ) ) {
79            if ( dynamic_cast< TypeInstType* >( varExpr->get_var()->get_type() ) ) {
80                modVars.insert( varExpr->get_var()->get_uniqueId() );
81            } // if
82        } // if
83    }
84} // namespace GenPoly
Note: See TracBrowser for help on using the repository browser.