📄 tree.cc
字号:
(tree_node_[x].name()=="volatile")) {
stype_all.push_back(tree_node_[x].name());
// have to handle pointers differently since they are per variable
} else if (tree_node_[x].name() == "pointer") {
stype_one.push_back(tree_node_[x].name());
// data type
} else if (node_parent_name(x) == "type") {
if ((tree_node_[x].name() != "signed") &&
(tree_node_[x].name() != "unsigned")) {
if (tree_node_[x].name() != "struct_or_union") {
type = tree_node_[x].name();
} else {
long tmp = tree_node_[x].child(0);
if (node_child_name(tmp, 1) != "{") {
type = "struct " + node_child_name(tmp, 1);
} else {
type = "struct unknown";
}
}
}
// ends a list of declarations (clear out stuff like extern, const,etc)
} else if ((tree_node_[x].name() == "declaration") ||
(tree_node_[x].name() == "(")) {
stype_one.clear();
stype_all.clear();
// ends declaration of a single variable so clear * in front of variable
} else if (tree_node_[x].name() == "declarator") {
stype_one.clear();
// end of an assignment
} else if (tree_node_[x].name() == "assignment_expr") {
if (curr_function) {
function_[curr_function].add_action("assign_end", ASSIGN_END, x);
}
pair <long, long> p (x - tree_node_[x].subtree_size(), x);
function_[curr_function].add_assign_node (p);
// end of a statement
} else if (tree_node_[x].name() == "statement") {
if (curr_function) {
function_[curr_function].add_action("statement_end",STATE_END,x);
function_[curr_function].add_action("#"+to_string(x),STATE_NUM,x);
}
// ++/-- bindings
} else if (tree_node_[x].name() == "short_assign_op") {
Rassert(curr_function);
string op_target = get_first_var_child(x, curr_function);
function_[curr_function].add_action(op_target, SHORT_ASSIGN_VAR, x);
// separates sources and targets of assignments
} else if ((tree_node_[x].name() == "assignment_operator") ||
(tree_node_[x].name() == ">>=") ||
(tree_node_[x].name() == "<<=") ||
(tree_node_[x].name() == "+=") ||
(tree_node_[x].name() == "-=") ||
(tree_node_[x].name() == "*=") ||
(tree_node_[x].name() == "/=") ||
(tree_node_[x].name() == "%=") ||
(tree_node_[x].name() == "&=") ||
(tree_node_[x].name() == "^=") ||
(tree_node_[x].name() == "|=")) {
if (curr_function) {
function_[curr_function].add_action("assignment", ASSIGN, x);
}
// get commas which separate args in func_call
} else if (tree_node_[x].name() == ",") {
if (func_call.size()) {
function_[curr_function].add_func_call_comma(
func_call[func_call.size()-1]);
}
// get elipses: tell func it can have variable args
} else if (tree_node_[x].name() == "...") {
Rassert(curr_function);
function_[curr_function].add_elipses();
// to evaluate bracket contents in correct order
} else if (tree_node_[x].name() == "[") {
if (curr_function) {
function_[curr_function].add_action ("[", BRAC_OPEN, x);
}
// to evaluate bracket contents in correct order
} else if (tree_node_[x].name() == "]") {
if (curr_function) {
function_[curr_function].add_action ("]", BRAC_CLOSE, x);
}
// beginning of conditional statements
} else if ((tree_node_[x].name() == "if") ||
(tree_node_[x].name() == "switch")) {
Rassert(curr_function);
function_[curr_function].add_action("select_start", SELECT_START, x);
// end of conditional statement
} else if ((tree_node_[x].name() == "else") ||
(tree_node_[x].name() == "case") ||
(tree_node_[x].name() == "default") {
Rassert(curr_function);
function_[curr_function].add_action("select_case", SELECT_CASE, x);
} else if (tree_node_[x].name() == "selection_statement") {
Rassert(curr_function);
function_[curr_function].add_action("select_end", SELECT_END, x);
// beginning of loop
} else if ((tree_node_[x].name() == "while") ||
(tree_node_[x].name() =="do") ||
(tree_node_[x].name() == "for")) {
Rassert(curr_function);
function_[curr_function].add_action("loop_start", LOOP_START, x);
// end of loop
} else if (tree_node_[x].name() == "iteration_statement") {
Rassert(curr_function);
function_[curr_function].add_action("loop_end", LOOP_END, x);
}
}
}
//------------------------------------------------------------
// Annotated C code for profiling
// ------------------------------
// Generates timing information and sizeof calls to get data type
// sizes. Requires linking profiled executable with KSVtime.c
//------------------------------------------------------------
void DB::print_annotated_c ()
{
// for printing new_cfile
long fdnl_num = 0;
bool in_global_def = true;
string newc_str;
long stack = 0;
long prev_str_x = -1;
bool sflag = false;
// Open output file for annotated c code output
ofstream new_cfile;
string str = ArgPack::ap().get_fname() + "_new.c";
new_cfile.open(str.c_str());
Rassert(new_cfile);
new_cfile << "extern void KSVprint_time (char *str, long node);\n";
new_cfile << "extern void KSVprint_size (void * s);\n";
new_cfile << "extern void KSVinit_time ();\n";
new_cfile << "extern void KSVend_time ();\n";
MAP (x, tree_node_.size()) {
if ((tree_node_[x].name()=="if") || (tree_node_[x].name()=="switch")) {
newc_str = "select_start";
sflag = true;
} else if ((tree_node_[x].name() == "while") ||
(tree_node_[x].name() =="do") ||
(tree_node_[x].name() == "for")) {
newc_str = "loop_start";
sflag = true;
} else if ((tree_node_[x].name() == "{") ||
(tree_node_[x].name() == "declaration_list")) {
Rassert(x>1);
long p = tree_node_[x].parent();
if (((tree_node_[x-1].name() == "declarator") &&
(tree_node_[x-2].name() == "function")) ||
(tree_node_[p].name() == "function_body")) {
fdnl_num++;
in_global_def = false;
newc_str = "fn_start";
new_cfile << "\n{\n";
if (func_def_name_list_[fdnl_num] == "main") {
new_cfile << "FILE * KSVfout;\n";
new_cfile << "KSVfout = fopen(\"KSV.annote\",\"w\");\n";
if (ArgPack::ap().calculate_edge_lengths()) {
MAP (y, variable_.size()) {
string tmp_s = variable_[y].type();
if (!tmp_s.empty()) {
if (undefined_structs_.find(tmp_s) ==
undefined_structs_.end()) {
new_cfile << "fprintf(KSVfout, \"" << tmp_s.c_str()
<< " %d\\n\", sizeof(" << tmp_s.c_str();
new_cfile << "));\n" << endl;
}
}
}
}
new_cfile << "fprintf (KSVfout,\"KSV type_size complete"
<< "\\n\");\n" << endl;
new_cfile << "fclose(KSVfout);\n";
new_cfile << "\nKSVinit_time();\n";
new_cfile << "atexit(KSVend_time);\n";
}
}
} else if (tree_node_[x].name() == "function_body") {
newc_str = "fn_done";
} else if (tree_node_[x].name() == "statement") {
if (prev_str_x != (x - 1)) {
newc_str = "statement_end";
}
} else if (tree_node_[x].name() == "iteration_statement") {
newc_str = "loop_end";
stack--;
} else if (tree_node_[x].name() == "selection_statement") {
newc_str = "select_end";
stack--;
}
string full_str;
if (!in_global_def) {
full_str = func_def_name_list_[fdnl_num] + " " + newc_str;
}
if ((!stack) && newc_str.size()) {
new_cfile << "\nKSVprint_time(\"" << full_str << "\", "<<x<< ");\n";
}
if (sflag) {
stack++;
sflag = false;
}
if (tree_node_[x].subtree_size() == 1) {
new_cfile << tree_node_[x].whitespace() << tree_node_[x].name();
}
if (newc_str == "fn_done") {
new_cfile << "\n}\n";
in_global_def = true;
}
if (newc_str.size()) {
prev_str_x = x;
newc_str = "";
}
}
new_cfile.close();
}
//------------------------------------------------------------
// Annotated c code for creating task graph
//-----------------------------------------
// Writes annotation comments to divide C program into tasks.
// Each comment is of the form 'KSV func_name number'.
// 'KSV func_name' is used to start a function, and 'KSV end'
// ends a function's annotation.
//------------------------------------------------------------
void DB::print_task_graph_c ()
{
// Open output file for annotated c code output
ofstream new_cfile;
string str = ArgPack::ap().get_fname() + "_tg.c";
new_cfile.open(str.c_str());
Rassert(new_cfile);
long fdnl_num = 0;
bool in_global_def = true;
string newc_str;
RVector<long> starts;
long starts_index = 0;
MAP (x, tree_node_.size()) {
if (tree_node_[x].name() == "{") {
Rassert(x>1);
if (tree_node_[x-1].name() == "declarator") {
if (tree_node_[x-2].name() == "function") {
fdnl_num++;
in_global_def = false;
new_cfile << "\n/*KSV " << func_def_name_list_[fdnl_num]
<< "*/";
long fn = func_map(func_def_name_list_[fdnl_num]);
starts = fg_[fn].tree_node_starts();
starts_index = 0;
}
}
} else if (tree_node_[x].name() == "function_body") {
new_cfile << "\n/*KSV end*/\n";
in_global_def = true;
starts.clear();
starts_index = 0;
}
if (starts_index < starts.size()) {
if (x >= starts[starts_index]) {
new_cfile << "\n/*KSV " << func_def_name_list_[fdnl_num]
<< " " << starts_index++ << "*/";
}
}
string full_str;
// Prints out original code w/ original whitespace (minus comments)
if (tree_node_[x].subtree_size() == 1) {
new_cfile << tree_node_[x].whitespace() << tree_node_[x].name();
}
}
new_cfile.close();
}
// Prints original code to stdout
void DB::print_terminals () const
{
MAP (x, tree_node_.size()) {
if (tree_node_[x].subtree_size() == 1)
cout << tree_node_[x].name() << endl;
}
}
// prints the abstract syntax tree (AST) in vcg format so it can be seen
void DB::print_tree_vcg () const
{
ofstream out;
string file_name = ArgPack::ap().get_fname() + ".vcg";
out.open(file_name.c_str());
if (!out) {
cout << "Cannot open output file";
Rabort();
}
out << "graph: { label: \"" << file_name << "\"\n";
MAP (x, tree_node_.size()) {
out << " node: { title: \""
<< x << "\" label: \"";
string s = tree_node_[x].name();
if (s[0] == '"') {
out << "\\\"";
} else if (s[0] == '\\') {
out << "\\\\";
} else {
out << s << "(" << x << ")";
}
out << "\" } \n";
}
MAP (x, tree_node_.size()) {
if (tree_node_[x].parent() != -1) {
out << " edge: { thickness: 2 sourcename:\""
<< tree_node_[x].parent() << "\" targetname: \""
<< x << "\" }\n";
}
}
out << "}\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -