User Guide
local_var_rename_visitor.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2023 Blue Brain Project, EPFL.
3  * See the top-level LICENSE file for details.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #pragma once
9 
10 /**
11  * \file
12  * \brief \copybrief nmodl::visitor::LocalVarRenameVisitor
13  */
14 
15 #include <map>
16 #include <stack>
17 #include <string>
18 
19 #include "symtab/decl.hpp"
20 #include "visitors/ast_visitor.hpp"
21 
22 namespace nmodl {
23 namespace visitor {
24 
25 /**
26  * \addtogroup visitor_classes
27  * \{
28  */
29 
30 /**
31  * \class LocalVarRenameVisitor
32  * \brief %Visitor to rename local variables conflicting with global scope
33  *
34  * Motivation: During inlining we have to do data-flow-analysis. Consider
35  * below example:
36  *
37  * \code{.mod}
38  * NEURON {
39  * RANGE tau, beta
40  * }
41  *
42  * DERIVATIVE states() {
43  * LOCAL tau
44  * ...
45  * rates()
46  * }
47  *
48  * PROCEDURE rates() {
49  * tau = beta * 0.12 * some_var
50  * }
51  * \endcode
52  *
53  * When rates() will be inlined into states(), local definition of tau will
54  * conflict with range variable tau. Hence we can't just copy the statements.
55  * Dataflow analysis could be done at the time of inlining. Other way is to run
56  * this pass before inlining and pre-rename any local-global variable conflicts.
57  * As we are renaming local variables only, it's safe and there are no side effects.
58  *
59  * \todo
60  * - Currently we are renaming variables even if there is no inlining candidates.
61  * In this case ideally we should not rename.
62  */
64  private:
65  /// non-null symbol table in the scope hierarchy
66  const symtab::SymbolTable* symtab = nullptr;
67 
68  /// symbol tables in case of nested blocks
69  std::stack<const symtab::SymbolTable*> symtab_stack;
70 
71  /// variables currently being renamed and their count
72  std::map<std::string, int> renamed_variables;
73 
74  public:
75  LocalVarRenameVisitor() = default;
76  void visit_statement_block(ast::StatementBlock& node) override;
77 };
78 
79 /** \} */ // end of visitor_classes
80 
81 } // namespace visitor
82 } // namespace nmodl
nmodl
encapsulates code generation backend implementations
Definition: ast_common.hpp:26
nmodl::visitor::LocalVarRenameVisitor::symtab
const symtab::SymbolTable * symtab
non-null symbol table in the scope hierarchy
Definition: local_var_rename_visitor.hpp:66
nmodl::visitor::LocalVarRenameVisitor::LocalVarRenameVisitor
LocalVarRenameVisitor()=default
nmodl::visitor::AstVisitor
Concrete visitor for all AST classes.
Definition: ast_visitor.hpp:37
nmodl::symtab::SymbolTable
Represent symbol table for a NMODL block.
Definition: symbol_table.hpp:57
nmodl::visitor::LocalVarRenameVisitor::renamed_variables
std::map< std::string, int > renamed_variables
variables currently being renamed and their count
Definition: local_var_rename_visitor.hpp:72
nmodl::visitor::LocalVarRenameVisitor::symtab_stack
std::stack< const symtab::SymbolTable * > symtab_stack
symbol tables in case of nested blocks
Definition: local_var_rename_visitor.hpp:69
nmodl::ast::StatementBlock
Represents block encapsulating list of statements.
Definition: statement_block.hpp:53
nmodl::visitor::LocalVarRenameVisitor::visit_statement_block
void visit_statement_block(ast::StatementBlock &node) override
rename name conflicting variables in the statement block and it's all children
Definition: local_var_rename_visitor.cpp:23
nmodl::visitor::LocalVarRenameVisitor
Visitor to rename local variables conflicting with global scope
Definition: local_var_rename_visitor.hpp:63
decl.hpp
Forward declarations of symbols in namespace nmodl::symtab.
ast_visitor.hpp
Concrete visitor for all AST classes.