source: translator/ControlStruct/LabelFixer.cc @ d9a0e76

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

remove Parser.old, add -XCFA to driver, copy ptrdiff_t from stddef.h in preclude, remove casts from initialization constants, adjust formatting

  • Property mode set to 100644
File size: 4.0 KB
Line 
1#include <list>
2#include <cassert>
3
4#include "LabelFixer.h"
5#include "MLEMutator.h"
6#include "SynTree/Statement.h"
7#include "SynTree/Declaration.h"
8#include "utility.h"
9
10namespace ControlStruct {
11    LabelFixer::Entry::Entry( Statement *to, Statement *from ) : definition ( to ) {
12        if ( from != 0 )
13            usage.push_back( from );
14    }
15
16    bool LabelFixer::Entry::insideLoop() {
17        return ( dynamic_cast< ForStmt * > ( definition ) ||
18                 dynamic_cast< WhileStmt * > ( definition )  );
19    }
20
21    LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) {
22        if ( generator == 0 )
23            generator = LabelGenerator::getGenerator();
24    }
25
26    void LabelFixer::visit(FunctionDecl *functionDecl) {
27        if ( functionDecl->get_statements() != 0 )
28            functionDecl->get_statements()->accept( *this );
29
30        MLEMutator mlemut( resolveJumps(), generator );
31        functionDecl->acceptMutator( mlemut );
32    }
33
34    void LabelFixer::visit(Statement *stmt ) {
35        std::list< Label > &labels = stmt->get_labels();
36
37        if ( ! labels.empty() ) {
38            Label current = setLabelsDef( labels, stmt );
39            labels.clear();
40            labels.push_front( current );
41        } // if
42    }
43
44    void LabelFixer::visit(BranchStmt *branchStmt) {
45        visit ( ( Statement * )branchStmt );  // the labels this statement might have
46
47        Label target;
48        if ( (target = branchStmt->get_target()) != "" ) {
49            setLabelsUsg( target, branchStmt );
50        } //else       /* computed goto or normal exit-loop statements */
51    }
52
53
54    Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
55        assert( definition != 0 );
56        Entry *entry = new Entry( definition );
57        bool used = false;
58
59        for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
60            if ( labelTable.find( *i ) == labelTable.end() )
61                { used = true; labelTable[ *i ] = entry; } // undefined and unused
62            else
63                if( labelTable[ *i ]->defined() )
64                    throw SemanticError("Duplicate definition of label: " + *i );
65                else
66                    labelTable[ *i ]->set_definition( definition );
67
68        if (! used ) delete entry;
69
70        return labelTable[ llabel.front() ]->get_label();  // this *must* exist
71    }
72
73    Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
74        assert( use != 0 );
75
76        if ( labelTable.find( orgValue ) != labelTable.end() )
77            labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
78        else
79            labelTable[ orgValue ] = new Entry( 0, use );
80
81        return labelTable[ orgValue ]->get_label();
82    }
83
84    std::map < Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
85        std::map < Statement *, Entry * > def_us;
86
87        for ( std::map < Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
88            Entry *e = i->second;
89
90            if ( def_us.find ( e->get_definition() ) == def_us.end() )
91                def_us[ e->get_definition() ] = e;
92            else
93                if(e->used())
94                    def_us[ e->get_definition() ]->add_uses( e->get_uses() );
95        }
96
97        // get rid of labelTable
98        for ( std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
99            Statement *to = (*i).first;
100            std::list < Statement *> &from = (*i).second->get_uses();
101            Label finalLabel = generator->newLabel();
102            (*i).second->set_label( finalLabel );
103
104            if ( to == 0 ) {
105                BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
106                Label undef("");
107                if ( first_use != 0 )
108                    undef = first_use->get_target();
109                throw SemanticError ( "'" + undef + "' label not defined");
110            }
111
112            to->get_labels().clear();
113            to->get_labels().push_back( finalLabel );
114
115            for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
116                BranchStmt *jumpTo = dynamic_cast < BranchStmt * > ( *j );
117                assert( jumpTo != 0 );
118                jumpTo->set_target( finalLabel );
119            } // for
120        } // for
121
122        // reverse table
123        std::map < Label, Statement * > *ret = new std::map < Label, Statement * >();
124        for (std::map < Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 
125            (*ret)[ (*i).second->get_label() ] = (*i).first;
126
127        return ret;
128    }
129}  // namespace ControlStruct
Note: See TracBrowser for help on using the repository browser.