source: src/ControlStruct/FixLabels.cpp@ 21fe17f

ADT ast-experimental enum forall-pointer-decay pthread-emulation qualifiedEnum
Last change on this file since 21fe17f was 21fe17f, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Clean-up the FixLabelsCore class and utilities.

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