Changeset 21fe17f


Ignore:
Timestamp:
Nov 5, 2021, 4:18:55 PM (3 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, enum, forall-pointer-decay, master, pthread-emulation, qualifiedEnum
Children:
817bb3c
Parents:
b8ab91a
Message:

Clean-up the FixLabelsCore? class and utilities.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/FixLabels.cpp

    rb8ab91a r21fe17f  
    1010// Created On       : Mon Nov  1 09:39:00 2021
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Nov  2 10:32:00 2021
    13 // Update Count     : 0
     12// Last Modified On : Mon Nov  5 16:05:00 2021
     13// Update Count     : 1
    1414//
    1515
     
    2626namespace {
    2727
    28 struct MultiLevelExitCore :
    29                 public ast::WithVisitorRef<MultiLevelExitCore>,
    30                 public ast::WithShortCircuiting, public ast::WithGuards {
    31         class Entry;
    32 };
    33 
    34 struct Entry {
    35         ast::Label label;
    36         const ast::Stmt * def;
    37 
    38         Entry() : label( CodeLocation() ), def( nullptr ) {}
    39         Entry( const ast::Stmt * def ) : label( def->location ), def( def ) {}
    40 
    41         bool isDefined() const {
    42                 return nullptr != def;
    43         }
    44 
    45         bool isInsideLoop() {
    46                 return ( dynamic_cast< const ast::ForStmt *>( def ) ||
    47                         dynamic_cast< const ast::WhileStmt *>( def ) );
    48         }
    49 };
    50 
    5128class FixLabelsCore final : public ast::WithGuards {
    52         std::map<ast::Label, Entry *> labelTable;
     29        LabelToStmt labelTable;
    5330        LabelGenerator_new * label_gen;
    5431public:
     
    5835        {}
    5936
    60         std::map<ast::Label, const ast::Stmt *> * resolveJumps();
    61 
    6237        void previsit( const ast::FunctionDecl * );
    6338        const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
     
    6641        void previsit( const ast::LabelAddressExpr * );
    6742
    68         ast::Label setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * );
    69         template<typename UsageNode>
    70         void setLabelsUsage(ast::Label, const UsageNode * usage );
     43        void setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * );
     44        void setLabelsUsage( const ast::Label & );
    7145};
    72 
    73 std::map<ast::Label, const ast::Stmt *> * FixLabelsCore::resolveJumps() {
    74         auto ret = new std::map<ast::Label, const ast::Stmt *>();
    75         for ( auto kvp : labelTable ) {
    76                 if ( !kvp.second->isDefined() ) {
    77                         SemanticError( kvp.first.location,
    78                                 "Use of undefined label: " + kvp.first.name );
    79                 }
    80                 (*ret)[ kvp.first ] = kvp.second->def;
    81         }
    82         return ret;
    83 }
    8446
    8547void FixLabelsCore::previsit( const ast::FunctionDecl * ) {
     
    9052                const ast::FunctionDecl * decl ) {
    9153        if ( nullptr == decl->stmts ) return decl;
     54        for ( auto kvp : labelTable ) {
     55                if ( nullptr == kvp.second ) {
     56                        SemanticError( kvp.first.location,
     57                                "Use of undefined label: " + kvp.first.name );
     58                }
     59        }
     60        LabelToStmt * copy = new LabelToStmt( labelTable );
    9261        return ast::mutate_field( decl, &ast::FunctionDecl::stmts,
    93                 multiLevelExitUpdate( decl->stmts.get(), resolveJumps(), label_gen ) );
     62                multiLevelExitUpdate( decl->stmts.get(), copy, label_gen ) );
    9463}
    9564
    9665void FixLabelsCore::previsit( const ast::Stmt * stmt ) {
    97         if ( stmt->labels.empty() ) {
    98                 return;
     66        if ( !stmt->labels.empty() ) {
     67                setLabelsDef( stmt->labels, stmt );
    9968        }
    100         // Only remember one label for each statement.
    101         // (But we don't do anything with one label. What does it do?)
    102         ast::Label current = setLabelsDef( stmt->labels, stmt );
    10369}
    10470
    10571void FixLabelsCore::previsit( const ast::BranchStmt * stmt ) {
    10672        if ( !stmt->labels.empty() ) {
    107                 ast::Label current = setLabelsDef( stmt->labels, stmt );
     73                setLabelsDef( stmt->labels, stmt );
    10874        }
    10975        if ( !stmt->target.empty() ) {
    110                 setLabelsUsage( stmt->target, stmt );
     76                setLabelsUsage( stmt->target );
    11177        }
    11278}
     
    11480void FixLabelsCore::previsit( const ast::LabelAddressExpr * expr ) {
    11581        assert( !expr->arg.empty() );
    116         setLabelsUsage( expr->arg, expr );
     82        setLabelsUsage( expr->arg );
    11783}
    11884
    119 ast::Label FixLabelsCore::setLabelsDef(
     85void FixLabelsCore::setLabelsDef(
    12086                const std::vector<ast::Label> & labels, const ast::Stmt * stmt ) {
    12187        assert( !labels.empty() );
     
    12591                if ( labelTable.find( label ) == labelTable.end() ) {
    12692                        // Make sure to only create the entry once.
    127                         labelTable[ label ] = new Entry( stmt );
    128                 } else if ( labelTable[ label ]->isDefined() ) {
     93                        labelTable[ label ] = stmt;
     94                } else if ( nullptr != labelTable[ label ] ) {
    12995                        // Duplicate definition, this is an error.
    13096                        SemanticError( label.location,
     
    13298                } else {
    13399                        // Perviously used, but not defined until now.
    134                         // (There was a question about changing objects, is that the Entry?)
    135                         delete labelTable[ label ];
    136                         labelTable[ label ] = new Entry( stmt );
     100                        labelTable[ label ] = stmt;
    137101                }
    138102        }
    139 
    140         // Return the labels on this statement to be the tmp. canonical label.
    141         return labelTable[ labels.front() ]->label;
    142103}
    143104
    144105// Label was used, if it is new add it to the table.
    145 // (Why do we pass in usage? It's only use is in the assertion.)
    146 template<typename UsageNode>
    147 void FixLabelsCore::setLabelsUsage(ast::Label label, const UsageNode * usage ) {
    148         assert( usage );
    149 
     106void FixLabelsCore::setLabelsUsage( const ast::Label & label ) {
    150107        if ( labelTable.find( label ) == labelTable.end() ) {
    151                 labelTable[ label ] = new Entry();
     108                labelTable[ label ] = nullptr;
    152109        }
    153110}
Note: See TracChangeset for help on using the changeset viewer.