14 #include "utils/logger.hpp"
19 using printer::JSONPrinter;
36 return "CONDITIONAL_BLOCK";
48 throw std::runtime_error(
"Unhandled DUState?");
71 std::ostringstream stream;
76 for (
const auto& instance:
chain) {
77 instance.print(printer);
92 const auto& child_state = chain.eval(variable_type);
136 bool block_with_none =
false;
139 auto child_state = chain.eval(variable_type);
146 block_with_none =
true;
179 for (
auto& inst:
chain) {
195 node.visit_children(*
this);
205 const auto& function_name =
node.get_node_name();
207 if (symbol ==
nullptr || symbol->is_external_variable()) {
208 node.visit_children(*
this);
215 const auto& symtab =
node.get_symbol_table();
216 if (symtab !=
nullptr) {
221 node.visit_children(*
this);
232 if (is_outer_binary_expression) {
234 node.get_shared_ptr());
237 node.get_rhs()->visit_children(*
this);
241 node.get_lhs()->visit_children(*
this);
244 if (is_outer_binary_expression) {
260 node.get_condition()->accept(*
this);
261 const auto& block =
node.get_statement_block();
263 block->accept(*
this);
268 for (
const auto& item:
node.get_elseifs()) {
273 if (
node.get_elses()) {
328 const auto&
name =
node.get_node_name();
329 const auto& length =
node.get_length();
334 if (!length->is_integer()) {
337 if (
name == variable_name_prefix) {
344 auto index = std::dynamic_pointer_cast<ast::Integer>(length);
371 assert(symbol !=
nullptr);
373 const auto properties = NmodlType::local_var | NmodlType::argument;
374 const auto is_local = symbol->has_any_property(properties);
400 std::ostringstream fullname;
410 node.visit_children(*
this);
427 auto global_symbol_properties = NmodlType::global_var | NmodlType::range_var |
428 NmodlType::assigned_definition;
432 if (global_symbol !=
nullptr && global_symbol->has_any_property(global_symbol_properties)) {
444 node.visit_children(*
this);
Auto generated AST classes declaration.
Represents an argument to functions and procedures.
Represents binary expression in the NMODL.
Represents CONDUCTANCE statement in NMODL.
Represent CONSERVE statement in NMODL.
Represents specific element of an array variable.
One equation in a system of equations tha collectively form a LINEAR block.
Base class for all AST node.
One equation in a system of equations that collectively make a NONLINEAR block.
Represents block encapsulating list of statements.
Represents a C code block.
Helper class for printing AST in JSON form.
void flush()
Dump json object to stream (typically at the end) nspaces is number of spaces used for indentation.
void add_node(std::string value, const std::string &key="name")
Add node to json (typically basic type)
void compact_json(bool flag)
print json in compact mode
void push_block(const std::string &value, const std::string &key="name")
Add new json object (typically start of new block) name here is type of new block encountered.
void pop_block()
We finished processing a block, add processed block to it's parent block.
std::shared_ptr< Symbol > lookup_in_scope(const std::string &name) const
check if symbol with given name exist in the current table (including all parents)
Def-Use chain for an AST node.
std::string to_string(bool compact=true) const
return json representation
std::vector< DUInstance > chain
def-use chain for a variable
DUVariableType variable_type
type of variable
DUState eval() const
return "effective" usage of a variable
std::string name
name of the node
Represent use of a variable in the statement.
DUState eval(DUVariableType variable_type) const
analyze all children and return "effective" usage
DUState state
state of the usage
DUState conditional_block_eval(DUVariableType variable_type) const
evaluate global usage i.e. with [D,U] states of children
void print(printer::JSONPrinter &printer) const
DUInstance to JSON string.
std::vector< DUInstance > children
usage of variable in case of if like statements
DUState sub_block_eval(DUVariableType variable_type) const
if, elseif and else evaluation
DUVariableType variable_type
variable type (Local or Global)
bool unsupported_node
indicate that there is unsupported construct encountered
void visit_name(const ast::Name &node) override
visit node of type ast::Name
symtab::SymbolTable * current_symtab
symbol table for current statement block (or of parent block if doesn't have) should be initialized b...
symtab::SymbolTable * global_symtab
symbol table containing global variables
void visit_indexed_name(const ast::IndexedName &node) override
visit node of type ast::IndexedName
void visit_binary_expression(const ast::BinaryExpression &node) override
Nmodl grammar doesn't allow assignment operator on rhs (e.g.
DUChain analyze(const ast::Ast &node, const std::string &name)
compute def-use chain for a variable within the node
void visit_non_lin_equation(const ast::NonLinEquation &node) override
visit node of type ast::NonLinEquation
void visit_conductance_hint(const ast::ConductanceHint &node) override
statements / nodes that should not be used for def-use chain analysis
void visit_from_statement(const ast::FromStatement &node) override
visit node of type ast::FromStatement
void start_new_chain(DUState state)
void visit_function_call(const ast::FunctionCall &node) override
Nothing to do if called function is not defined or it's external but if there is a function call for ...
bool visiting_lhs
starting visiting lhs of assignment statement
void visit_conserve(const ast::Conserve &node) override
visit node of type ast::Conserve
void visit_with_new_chain(const ast::Node &node, DUState state)
void visit_local_list_statement(const ast::LocalListStatement &node) override
visit node of type ast::LocalListStatement
std::vector< DUInstance > * current_chain
def-use chain currently being constructed
bool ignore_verbatim
ignore verbatim blocks
void visit_verbatim(const ast::Verbatim &node) override
We are not analyzing verbatim blocks yet and hence if there is a verbatim block we assume there is va...
void process_variable(const std::string &name)
void visit_reaction_statement(const ast::ReactionStatement &node) override
unsupported statements : we aren't sure how to handle this "yet" and hence variables used in any of t...
void visit_if_statement(const ast::IfStatement &node) override
visit node of type ast::IfStatement
void visit_statement_block(const ast::StatementBlock &node) override
visit node of type ast::StatementBlock
std::stack< symtab::SymbolTable * > symtab_stack
symbol tables in call hierarchy
void visit_var_name(const ast::VarName &node) override
visit node of type ast::VarName
void update_defuse_chain(const std::string &name)
Update the Def-Use chain for given variable.
void visit_unsupported_node(const ast::Node &node)
std::shared_ptr< const ast::BinaryExpression > current_binary_expression
void visit_argument(const ast::Argument &node) override
visit node of type ast::Argument
std::string variable_name
variable for which to construct def-use chain
void visit_lin_equation(const ast::LinEquation &node) override
visit node of type ast::LinEquation
Visitor to return Def-Use chain for a given variable in the block/node
NmodlType
NMODL variable properties.
std::string to_string(DUState state)
DUState to string conversion for pretty-printing.
DUState
Represent a state in Def-Use chain.
@ CONDITIONAL_BLOCK
conditional block
@ CD
global or local variable is conditionally defined
@ U
global variable is used
@ LU
local variable is used
@ LD
local variable is defined
@ NONE
variable is not used
@ D
global variable is defined
DUVariableType
Variable type processed by DefUseAnalyzeVisitor.
std::ostream & operator<<(std::ostream &os, DUState state)
encapsulates code generation backend implementations
std::string to_nmodl(const ast::Ast &node, const std::set< ast::AstNodeType > &exclude_types)
Given AST node, return the NMODL string representation.
static Node * node(Object *)
Base class for all Abstract Syntax Tree node types.