bool HostProgramTuning::VisitCallExpr(CallExpr *E) { if (E != NULL){ QualType q = E->getType(); const Type *t = q.getTypePtrOrNull(); if(t != NULL) { FunctionDecl *func = E->getDirectCallee(); if (!func) return false; ProcessFuncCall(func->getNameInfo().getName().getAsString(), E); } } return true; }
/* this helper function is called when the traversal reaches a node of type Decl */ bool DeclHelper(Decl *D){ const Stmt* parent = getStmtParent(D, Context); //const Stmt* parentsParent = getStmtParent(parent, Context); //if it is part of the (init; condition; increment) of a for loop, we don't care about it if(isFlowControl(D, Context)){ return false; } //supresses the catch stmt's arguments if(parent != NULL && strcmp(parent->getStmtClassName(), "CXXCatchStmt") == 0){ return true; } string filename; if(!isInCurFile(Context, D, filename) && filename.size() != 0){ return false; }else if(filename.size() == 0){ return true; } string output = ""; //get the name of the node type string node = D->getDeclKindName(); //calculate the current level, nextLevel, and previousLevel int intLevel = getLevelDecl(D);int intNextLevel = intLevel+1; int intNextNextLevel = intLevel+2; int intPrevLevel = intLevel-1; //create string values for the levels to use as output string level; string nextLevel; string nextNextLevel; string prevLevel; stringstream ss; stringstream ss2; stringstream ss3; stringstream ss4; ss << intLevel; level = ss.str(); ss2 << intNextLevel; nextLevel = ss2.str(); ss3 << intPrevLevel; prevLevel = ss3.str(); ss4 << intNextNextLevel; nextNextLevel = ss4.str(); if(callStackDebug && !callStack.empty()){ cerr << "decl: call stack top: " << callStack.top()->getStmtClassName() << endl; } //if top of stack is no longer a parent while(!callStack.empty() && numClosingArgsNeeded > 0 && !isParentDecl(D, callStack.top()->getStmtClassName())){ if(debugPrint){ cerr << "adding args" << endl; } numClosingArgsNeeded--; output += "</args,1>\n"; callStack.pop(); if(callStackDebug){ cerr << "poping" << endl; printCallStack(); } } //add new calls to stack if(isParentDeclInCurFile(D,"CXXConstructExpr") && isParentDecl(D, "CXXConstructExpr")){ if(debugPrint){ cerr << "setting previousConstructorCall to true" << endl; } }else if(isParentDeclInCurFile(D,"CXXTemporaryObjectExpr") && isParentDecl(D, "CXXTemporaryObjectExpr")){ if(debugPrint){ cerr << "setting previousTempConstructorCallArg" << endl; } }else if(isParentDecl(D, "CallExpr")){ if(debugPrint){ cerr << "setting previousCallArgs to true" << endl; } }else if(isParentDecl(D, "CXXMemberCallExpr")){ if(debugPrint){ cerr << "setting previousMemberCallArg to true" << endl; } } if(isParentDecl(getDeclParent(D, Context), "Var")){ previousRhsDecl = true; if(debugPrint){ cout << "setting prev var to true" << endl; } }else if(previousRhsDecl && numClosingVarsNeeded > 0){ //if the current node is not a child of a variable declaration //but the previous node was a child of a variable declation //then we know to print a </decl> output +="</variableDecl,1>\n"; numClosingVarsNeeded--; previousRhsDecl = false; } if(node == "Var"){ output += "<variableDecl, " + prevLevel + ">"; numClosingVarsNeeded++; VarDecl* VD = (VarDecl*) D; if(!VD->hasInit()){ output +="\n</variableDecl,1>\n"; numClosingVarsNeeded--; } }else if(node == "Function"){ FunctionDecl* FD = (FunctionDecl*) D; output += "<functionDef," + level +">"; //add function name to the output output += "\n<name: " + FD->getNameInfo().getAsString() + "," + nextLevel + ">"; }else if(node == "CXXRecord"){ const Decl* parent = getDeclParent(D, Context); if(parent && strcmp(parent->getDeclKindName(), "CXXRecord") != 0){ CXXRecordDecl* CD = (CXXRecordDecl*) D; output += "<classDef," + level + ">"; output += "\n<name: " + CD->getNameAsString() + "," + nextLevel + ">"; output += "\n<bases," + nextLevel + ">"; //iterate over all bases and add them to the output CXXRecordDecl::base_class_iterator basesItr = CD->bases_begin(); while(basesItr != CD->bases_end()){ QualType qt = basesItr->getType(); output += "\n<base: " + qt.getBaseTypeIdentifier()->getName().str(); output += "," + nextNextLevel + ">"; basesItr++; } //iterate over all of the virtual bases and add them to the output auto vBasesItr = CD->vbases_begin(); while(vBasesItr != CD->vbases_end()){ QualType qt = vBasesItr->getType(); output += "\n<base: " + qt.getBaseTypeIdentifier()->getName().str(); output += "," + nextNextLevel + ">"; vBasesItr++; } } }else if(node == "CXXDestructor"){ CXXDestructorDecl* CD = (CXXDestructorDecl*) D; if(!CD->isImplicit()){ output += "<functionDef," + level +">"; //add function name to the output output += "\n<name: ~" + CD->getNameInfo().getAsString() + "," + nextLevel + ">"; } }else if(node == "CXXConstructor"){ CXXConstructorDecl* CD = (CXXConstructorDecl*) D; if(!CD->isImplicit()){ output += "<functionDef," + level +">"; //add function name to the output output += "\n<name: " + CD->getNameInfo().getAsString() + "," + nextLevel + ">"; } }else if(node == "CXXMethod"){ CXXMethodDecl* CM = (CXXMethodDecl*) D; if(!CM->isImplicit()){ output += "<functionDef," + level +">"; //add function name to the output output += "\n<name: " + CM->getNameInfo().getAsString() + "," + nextLevel + ">"; } }else{ if(debugPrint){ output += "<"; output += node; output += ">"; } } if(output.size() != 0){ cout << output << endl; } return true; }
bool VisitCallExpr(CallExpr* call) { //outs() << "do found" << "\n"; NamedDecl* calleedecl = (NamedDecl*)call->getCalleeDecl(); if (calleedecl != NULL) { //ignore macro expansion SourceLocation loc = call->getLocStart(); if (!sm->isInMainFile(loc)) return true; if (call->getCalleeDecl()->isFunctionOrFunctionTemplate()) { SourceRange sr = call->getCalleeDecl()->getAsFunction()->getSourceRange(); SourceLocation start_pos = sr.getBegin(); if (!start_pos.isValid()) { //outs() << "error: invalid location." << "\n"; //outfile << "error: invalid location." << "\n"; return true; } else { StringRef headerFilename = sm->getFilename(start_pos); string fullheaderfile = headerFilename.str(); if (fullheaderfile == "") return true; if (fullheaderfile.find(project_name) < fullheaderfile.length()) return true; if (fullheaderfile[0] != '/') return true; /* int i; for (i = fullheaderfile.length() - 1; i >=0; i--) if (fullheaderfile[i] == '/') break; string headerfile; if (fullheaderfile.substr(fullheaderfile.length()-2, 2) == ".h") headerfile = fullheaderfile.substr(i+1, fullheaderfile.length() - i - 3); else headerfile = fullheaderfile.substr(i+1, fullheaderfile.length() - i - 1); bool flag = false; for (int j = 0; j < API_NUM; j++) { bool flag2 = true; for (int k = 0; k < headerfile.length(); k++){ if (headerfile[k] != APIList[j][k]) flag2 = false; } if (flag2 == true){ flag = true; } } if (!flag) return true; */ } } else { //return true; } outs() << "Found " << calleedecl->getQualifiedNameAsString() <<" at: "; //outfile << "Found " << calleedecl->getQualifiedNameAsString() <<" at: "; string s = calleedecl->getQualifiedNameAsString(); qualified_name = ""; short_name = ""; unsigned int pos = s.length()-1; while (pos > 0) { if (s[pos] == ':' && s[pos-1] == ':') break; pos--; } if (pos == 0) pos = -1; short_name = s.substr(pos+1, s.length()-pos-1); int mark = 0; for (unsigned int i = 0; i < s.length(); i++) { if (s[i] == ',') s[i] = ';'; if (s[i] == '<') { mark ++; } if (i > 0) { if (s[i-1] == '>') { mark --; } } if (mark == 0 || i >= pos+1) qualified_name = qualified_name + s[i]; } StringRef filename = sm->getFilename(loc); //unsigned int col = sm->getSpellingColumnNumber(loc); //unsigned int line = sm->getSpellingLineNumber(loc); outs() << filename << "\n"; //file_name = filename.str(); //outfile << filename.str() << "\n"; //outfile <<filename.str(); //outs() << ", line: " <<line<< " column: " << col << "\n"; //outfile << ", line: " <<line<< " column: " << col << "\n"; //get parent function if (CurrentFunc != NULL) { SourceRange sr = CurrentFunc->getSourceRange(); SourceLocation start_pos = sr.getBegin(); SourceLocation end_pos = sr.getEnd(); start_line = sm->getSpellingLineNumber(start_pos); end_line = sm->getSpellingLineNumber(end_pos); outs() << "Function:" << CurrentFunc->getNameInfo().getAsString() <<", StartLine: " <<start_line<< " EndLine: " << end_line << "\n"; //outfile << "Function:" << CurrentFunc->getNameInfo().getAsString() <<", StartLine: " <<start_line<< " EndLine: " << end_line << "\n"; } else { outs() << "error: no parent func" << "\n"; //outfile << "error: no parent func" << "\n"; } //get header file if (call->getCalleeDecl()->isFunctionOrFunctionTemplate()) { SourceRange sr = call->getCalleeDecl()->getAsFunction()->getSourceRange(); SourceLocation start_pos = sr.getBegin(); if (!start_pos.isValid()) { outs() << "error: invalid location." << "\n"; return true; //outfile << "error: invalid location." << "\n"; } else { StringRef headerFilename = sm->getFilename(start_pos); outs() << "From declaration file:" << headerFilename<< ", line " << sm->getSpellingLineNumber(start_pos) <<"\n"; //outfile << "From declaration file:" << headerFilename.str()<< ", line " << sm->getSpellingLineNumber(start_pos) <<"\n"; header_file = headerFilename.str(); } } else { outs() << "error: header file not found(callee is not a function)" << "\n"; return true; //outfile << "error: header file not found(callee is not a function)" << "\n"; } outs() << "\n"; //outfile << "\n"; full_file_name = "D:/Code/Repos/r10k_cpp"+file_name; if (end_line < start_line) return true; if (end_line-start_line< 8) ranks = -(end_line-start_line-8); else ranks = (end_line-start_line-8); ranks = ranks / 3; //if (header_file != ""){ outfile<<short_name<<","<<qualified_name<<","<<full_file_name<<","<<start_line<<","<<end_line<<","<<ranks<<","<<project_name<<endl; //outfile<<project_name<<","<<file_name<<","<<qualified_name<<","<<short_name<<","<<header_file<<","<<start_line<<","<<end_line<<endl; //} return true; } else { //outs() << "null" << "\n"; return true; } }