source: src/ControlStruct/FixLabels.cpp @ 7d55e4d

Last change on this file since 7d55e4d was 37eb41b, checked in by Peter A. Buhr <pabuhr@…>, 3 years ago

formatting, remove anonymous namespace

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