void InstrumentCalls::InstrumentCallsFunctor::postorder(Context ctx, AST_t node) { ScopeLink scope_link = ctx.scope_link; AST_t called_expression_tree = node.get_attribute(LANG_CALLED_EXPRESSION); AST_t arguments_tree = node.get_attribute(LANG_FUNCTION_ARGUMENTS); Expression called_expression(called_expression_tree, scope_link); // Only function-names are considered here if (!called_expression.is_id_expression()) { // std::cerr << "Called expression is not an id expression" << std::endl; return; } IdExpression called_id_expression = called_expression.get_id_expression(); if (!_instrument_filter.match(called_id_expression.prettyprint())) return; std::string shadow_function_name = "_" + called_id_expression.mangle_id_expression() + "_instr"; if (defined_shadows.find(shadow_function_name) == defined_shadows.end()) { // The shadow has not been defined, define it here if (!define_shadow(called_id_expression, shadow_function_name)) { // Ignore this shadow return; } defined_shadows.insert(shadow_function_name); } // Now replace the arguments Source replaced_arguments; replaced_arguments << "\"" << node.get_file() << "\"" << "," << node.get_line() ; if (arguments_tree.prettyprint() != "") { replaced_arguments << "," << arguments_tree.prettyprint(/*commas=*/true); } // Now create an expression tree Source shadow_function_call; shadow_function_call << shadow_function_name << "(" << replaced_arguments << ")" ; AST_t shadow_function_call_tree = shadow_function_call.parse_expression(node, scope_link); node.replace(shadow_function_call_tree); }
//! Returns the enclosing statement AST_t AST_t::get_enclosing_statement() const { AST_t a = *this; while (a.is_valid() && !(TL::Bool)a.get_attribute(LANG_IS_STATEMENT)) { a = a.get_parent(); } return a; }