source: translator/ControlStruct/LabelFixer.cc @ 5c7fb6c

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 5c7fb6c was 6c3744e, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

add list initializer, formatting changes

  • 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    Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
54        assert( definition != 0 );
55        Entry *entry = new Entry( definition );
56        bool used = false;
57
58        for ( std::list< Label >::iterator i = llabel.begin(); i != llabel.end(); i++ )
59            if ( labelTable.find( *i ) == labelTable.end() )
60                { used = true; labelTable[ *i ] = entry; } // undefined and unused
61            else
62                if ( labelTable[ *i ]->defined() )
63                    throw SemanticError( "Duplicate definition of label: " + *i );
64                else
65                    labelTable[ *i ]->set_definition( definition );
66
67        if (! used ) delete entry;
68
69        return labelTable[ llabel.front() ]->get_label();  // this *must* exist
70    }
71
72    Label LabelFixer::setLabelsUsg( Label orgValue, Statement *use ) {
73        assert( use != 0 );
74
75        if ( labelTable.find( orgValue ) != labelTable.end() )
76            labelTable[ orgValue ]->add_use( use );         // the label has been defined or used before
77        else
78            labelTable[ orgValue ] = new Entry( 0, use );
79
80        return labelTable[ orgValue ]->get_label();
81    }
82
83    std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticError ) {
84        std::map< Statement *, Entry * > def_us;
85
86        for ( std::map< Label, Entry *>::iterator i = labelTable.begin(); i != labelTable.end(); i++ ) {
87            Entry *e = i->second;
88
89            if ( def_us.find ( e->get_definition() ) == def_us.end() )
90                def_us[ e->get_definition() ] = e;
91            else
92                if ( e->used() )
93                    def_us[ e->get_definition() ]->add_uses( e->get_uses() );
94        }
95
96        // get rid of labelTable
97        for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) {
98            Statement *to = (*i).first;
99            std::list< Statement *> &from = (*i).second->get_uses();
100            Label finalLabel = generator->newLabel();
101            (*i).second->set_label( finalLabel );
102
103            if ( to == 0 ) {
104                BranchStmt *first_use = dynamic_cast<BranchStmt *>(from.back());
105                Label undef("");
106                if ( first_use != 0 )
107                    undef = first_use->get_target();
108                throw SemanticError ( "'" + undef + "' label not defined");
109            }
110
111            to->get_labels().clear();
112            to->get_labels().push_back( finalLabel );
113
114            for ( std::list< Statement *>::iterator j = from.begin(); j != from.end(); j++ ) {
115                BranchStmt *jumpTo = dynamic_cast< BranchStmt * > ( *j );
116                assert( jumpTo != 0 );
117                jumpTo->set_target( finalLabel );
118            } // for
119        } // for
120
121        // reverse table
122        std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
123        for ( std::map< Statement *, Entry * >::iterator i = def_us.begin(); i != def_us.end(); i++ ) 
124            (*ret)[ (*i).second->get_label() ] = (*i).first;
125
126        return ret;
127    }
128}  // namespace ControlStruct
Note: See TracBrowser for help on using the repository browser.