source: src/ControlStruct/FixLabels.cpp @ f27331c

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since f27331c was a5a08a05, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Missed a few extra references to LabelGenerator?.

  • Property mode set to 100644
File size: 3.1 KB
RevLine 
[b8ab91a]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// FixLabels.cpp -- Normalizes labels and handles multi-level exit labels.
8//
9// Author           : Andrew Beach
10// Created On       : Mon Nov  1 09:39:00 2021
11// Last Modified By : Andrew Beach
[cb921d4]12// Last Modified On : Mon Nov  8 10:53:00 2021
13// Update Count     : 3
[b8ab91a]14//
15
16#include "FixLabels.hpp"
17
18#include "AST/Label.hpp"
19#include "AST/Pass.hpp"
20#include "AST/Stmt.hpp"
21#include "ControlStruct/MultiLevelExit.hpp"
22
23namespace ControlStruct {
24
25namespace {
26
27class FixLabelsCore final : public ast::WithGuards {
[21fe17f]28        LabelToStmt labelTable;
[b8ab91a]29public:
[a5a08a05]30        FixLabelsCore() : labelTable() {}
[b8ab91a]31
32        void previsit( const ast::FunctionDecl * );
33        const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
34        void previsit( const ast::Stmt * );
35        void previsit( const ast::BranchStmt * );
36        void previsit( const ast::LabelAddressExpr * );
37
[21fe17f]38        void setLabelsDef( const std::vector<ast::Label> &, const ast::Stmt * );
39        void setLabelsUsage( const ast::Label & );
[b8ab91a]40};
41
42void FixLabelsCore::previsit( const ast::FunctionDecl * ) {
43        GuardValue( labelTable ).clear();
44}
45
46const ast::FunctionDecl * FixLabelsCore::postvisit(
47                const ast::FunctionDecl * decl ) {
48        if ( nullptr == decl->stmts ) return decl;
[21fe17f]49        for ( auto kvp : labelTable ) {
50                if ( nullptr == kvp.second ) {
51                        SemanticError( kvp.first.location,
52                                "Use of undefined label: " + kvp.first.name );
53                }
54        }
[b8ab91a]55        return ast::mutate_field( decl, &ast::FunctionDecl::stmts,
[cb921d4]56                multiLevelExitUpdate( decl->stmts.get(), labelTable ) );
[b8ab91a]57}
58
59void FixLabelsCore::previsit( const ast::Stmt * stmt ) {
[21fe17f]60        if ( !stmt->labels.empty() ) {
61                setLabelsDef( stmt->labels, stmt );
[b8ab91a]62        }
63}
64
65void FixLabelsCore::previsit( const ast::BranchStmt * stmt ) {
66        if ( !stmt->labels.empty() ) {
[21fe17f]67                setLabelsDef( stmt->labels, stmt );
[b8ab91a]68        }
69        if ( !stmt->target.empty() ) {
[21fe17f]70                setLabelsUsage( stmt->target );
[b8ab91a]71        }
72}
73
74void FixLabelsCore::previsit( const ast::LabelAddressExpr * expr ) {
75        assert( !expr->arg.empty() );
[21fe17f]76        setLabelsUsage( expr->arg );
[b8ab91a]77}
78
[21fe17f]79void FixLabelsCore::setLabelsDef(
[b8ab91a]80                const std::vector<ast::Label> & labels, const ast::Stmt * stmt ) {
81        assert( !labels.empty() );
82        assert( stmt );
83
84        for ( auto label : labels ) {
85                if ( labelTable.find( label ) == labelTable.end() ) {
86                        // Make sure to only create the entry once.
[21fe17f]87                        labelTable[ label ] = stmt;
88                } else if ( nullptr != labelTable[ label ] ) {
[b8ab91a]89                        // Duplicate definition, this is an error.
90                        SemanticError( label.location,
91                                "Duplicate definition of label: " + label.name );
92                } else {
93                        // Perviously used, but not defined until now.
[21fe17f]94                        labelTable[ label ] = stmt;
[b8ab91a]95                }
96        }
97}
98
99// Label was used, if it is new add it to the table.
[21fe17f]100void FixLabelsCore::setLabelsUsage( const ast::Label & label ) {
[b8ab91a]101        if ( labelTable.find( label ) == labelTable.end() ) {
[21fe17f]102                labelTable[ label ] = nullptr;
[b8ab91a]103        }
104}
105
106} // namespace
107
108void fixLabels( ast::TranslationUnit & translationUnit ) {
109        ast::Pass<FixLabelsCore>::run( translationUnit );
110}
111
112} // namespace ControlStruct
113
114// Local Variables: //
115// tab-width: 4 //
116// mode: c++ //
117// compile-command: "make install" //
118// End: //
Note: See TracBrowser for help on using the repository browser.