source: src/ControlStruct/FixLabels.cpp@ 9317419

ADT ast-experimental
Last change on this file since 9317419 was 37eb41b, checked in by Peter A. Buhr <pabuhr@…>, 4 years ago

formatting, remove anonymous namespace

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