void CompassAnalyses::PreferFseekToRewind::Traversal:: visit(SgNode* node) { // Implement your traversal here. if(isSgFunctionCallExp(node)) { SgFunctionCallExp* callSite = isSgFunctionCallExp(node); if(callSite->get_function() != NULL) { SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(callSite->get_function()); if(functionRefExp != NULL) { SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol(); ROSE_ASSERT(functionSymbol != NULL); std::string functionName = functionSymbol->get_name().getString(); if(functionName == "rewind") { output->addOutput(new CheckerOutput(node)); } } } } } //End of the visit function.
void CompassAnalyses::StringTokenToIntegerConverter::Traversal:: visit(SgNode* node) { // Implement your traversal here. if(isSgFunctionCallExp(node)) { SgFunctionCallExp* callSite = isSgFunctionCallExp(node); if(callSite->get_function() != NULL) { SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(callSite->get_function()); if(functionRefExp != NULL) { SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol(); ROSE_ASSERT(functionSymbol != NULL); std::string functionName = functionSymbol->get_name().getString(); if(functionName == "atoi" || functionName == "atol" || functionName == "atoll" || functionName == "sscanf" ) { output->addOutput(new CheckerOutput(node)); } } } } } //End of the visit function.
void SecureFunctionTypeTraversal::visit(SgNode* sgn) { if(isSgFunctionCallExp(sgn)) { SgFunctionDeclaration* fndecl = isSgFunctionCallExp(sgn)->getAssociatedFunctionDeclaration(); string filename = fndecl->get_file_info()->get_filename(); if(filename != "compilerGenerated") { StringUtility::FileNameClassification classification; classification = StringUtility::classifyFileName(filename, this->sourcedir, this->trustedlibs); //StringUtility::FileNameLocation filetypeclassification = classification.getLocation(); //cout << sgn->unparseToString() << filename << " : " << classification.getLocation() << ", " << classification.getLibrary() << endl; bool isSecure; if(untrustedFunctions.find(fndecl->get_name().getString()) != untrustedFunctions.end()) { isSecure = false; } else if(classification.isLibraryCode() || classification.isUserCode()) { isSecure = true; } else { isSecure = false; } AstAttribute* attr = dynamic_cast<AstAttribute*> ( new SecureFunctionType(isSecure) ); sgn->setAttribute("SECURE_TYPE", attr); } } }
void ASLAnalysis::visit(SgNode* node){ // concrete classes of AST nodes switch(node->variantT()){ // naming scheme for variants: V_<classname> case V_SgFunctionDeclaration:{ SgFunctionDeclaration* fdecl=isSgFunctionDeclaration(node); if(SgFunctionDefinition* fdef=fdecl->get_definition()) { std::string functionName=fdecl->get_name().getString(); Sg_File_Info* ptrFileInfo=node->get_file_info(); std::string aslPrefix=""; if(ptrFileInfo){ aslPrefix=ptrFileInfo->get_filenameString()+"/"; } enterFunction(aslPrefix+functionName); // set function name and reset enumeration counter } } break; // function calls through function pointers case V_SgPointerDerefExp:{ if(isSgFunctionCallExp(node->get_parent()) && !(isSgFunctionCallExp(node->get_parent())->get_function() != node)){ #ifdef DEBUG std::cout<<"Function Pointer at call-site"<<std::endl; #endif storeLocalSite(node); callSiteCounter++; functionPointerCallCounter++; } } break; case V_SgFunctionCallExp:{ SgFunctionCallExp* fcall=isSgFunctionCallExp(node); if(SgFunctionRefExp* func=isSgFunctionRefExp(fcall->get_function())) { // SgFunctionSymbol* functionSymbol=func->get_symbol(); // std::string functionName=functionSymbol->get_name().getString(); callSiteCounter++; } } break; } }
/* * Fix op structure calls and inject debug names */ void OPSource::fixOpFunctions(SgNode *n) { SgName var_name; SgFunctionCallExp *fn = isSgFunctionCallExp(n); if(fn != NULL) { string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString(); if(fn_name.compare("op_decl_const")==0) { SgExprListExp* exprList = fn->get_args(); SgExpressionPtrList &exprs = exprList->get_expressions(); if( isSgStringVal(exprs.back()) == NULL ) { SgVarRefExp* varExp = isSgVarRefExp(exprs[1]); if(!varExp) { varExp = isSgVarRefExp(isSgAddressOfOp(exprs[1])->get_operand_i()); } if(varExp) { var_name = varExp->get_symbol()->get_name(); } cout << "---Injecting Debug Name for const: " << var_name.getString() << "---" << endl; exprList->append_expression(buildStringVal(var_name)); } } } }
/* * Check to see if a variable has its address taken in an I/O operation. */ bool RegisterPointers::isAddrTakenInIrrelevantFunc(SgVarRefExp* expr) { //TODO get function call name /*SgExprStatement* stmt = isSgExprStatement(getEnclosingStatement(expr)); if(!stmt) return false; SgFunctionCallExp* funcCall = isSgFunctionCallExp(stmt->get_expression()); if(!funcCall) return false; string name = NAME(funcCall->getAssociatedFunctionSymbol());*/ SgStatement* encStmt = getEnclosingStatement(expr); SgNode* parent = expr->get_parent(); SgFunctionCallExp* funcCall = NULL; while(parent != encStmt) { funcCall = isSgFunctionCallExp(parent); if(funcCall && (functions.find(NAME(funcCall->getAssociatedFunctionSymbol())) != functions.end())) return true; parent = parent->get_parent(); } /*set<string>::const_iterator funcIt = functions.begin(); for(funcIt = functions.begin(); funcIt != functions.end(); funcIt++) { if(name.find(*funcIt) != string::npos) return true; }*/ return false; }
bool findCallsWithFuncArgs2(SgNode *node, string &str) { SgExprStatement *statement; if (statement = isSgExprStatement(node)) { SgFunctionCallExp *call_exp; if (call_exp = isSgFunctionCallExp(statement->get_the_expr())) { m_nodes.clear(); m_nodes.insert(call_exp); m_domain.expand(&m_nodes, QRQueryDomain::all_children); m_domain.getNodes()->erase(call_exp); NodeQuery::VariantVector vector (V_SgFunctionCallExp); QRQueryOpVariant op(vector); op.performQuery(&m_domain, &m_range); unsigned hits = m_range.countRange(); if (hits) { set<SgNode *> *rnodes = m_range.getNodes(); for (set<SgNode *>::iterator iter = rnodes->begin(); iter != rnodes->end(); ) { SgFunctionCallExp *exp = (SgFunctionCallExp *) *iter; iter++; SgExpression *funcexpr = exp->get_function(); str += funcexpr->unparseToString(); if (iter != rnodes->end()) { str += ", "; } } return true; } } } return false; }
void CompassAnalyses::DiscardAssignment::Traversal:: visit(SgNode* node) { if (isSgAssignOp(node)) { // simple case: the parent of a "real" assignment op must be an // expression statement if (!isSgExprStatement(node->get_parent())) { output->addOutput(new CheckerOutput(node)); } else { // not so simple case: the parent is an expression statement, but if // that statement is an if/loop condition, we still want to complain SgNode *assignment = node->get_parent(); SgNode *p = assignment->get_parent(); SgDoWhileStmt *dws; SgForStatement *fs; SgIfStmt *is; SgSwitchStatement *ss; SgWhileStmt *ws; if ((dws = isSgDoWhileStmt(p)) && dws->get_condition() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((fs = isSgForStatement(p)) && fs->get_test() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((is = isSgIfStmt(p)) && is->get_conditional() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((ss = isSgSwitchStatement(p)) && ss->get_item_selector() == assignment) { output->addOutput(new CheckerOutput(node)); } else if ((ws = isSgWhileStmt(p)) && ws->get_condition() == assignment) { output->addOutput(new CheckerOutput(node)); } } } else if (SgMemberFunctionRefExp *mf = isSgMemberFunctionRefExp(node)) { // not so simple case: call to operator= member function that is not an // expression statement by itself SgFunctionCallExp *call = isSgFunctionCallExp(mf->get_parent()->get_parent()); if (call && !isSgExprStatement(call->get_parent()) && mf->get_parent() == call->get_function() && std::strcmp(mf->get_symbol()->get_name().str(), "operator=") == 0) { output->addOutput(new CheckerOutput(call)); } } } //End of the visit function.
void SecureFunctionTypeTraversalTest::visit(SgNode* sgn) { if(isSgFunctionCallExp(sgn)) { SecureFunctionType* attr = dynamic_cast<SecureFunctionType*> (sgn->getAttribute("SECURE_TYPE") ); ROSE_ASSERT(attr != NULL); cout << sgn->unparseToString() << ": " ; (attr->isSecure()) ? cout << "trusted\n" : cout << "untrusted\n"; } }
int main(int argc, char** argv) { SgProject* proj = frontend(argc,argv); SgFunctionDeclaration* mainDecl = SageInterface::findMain(proj); SgFunctionDefinition* mainDef = mainDecl->get_definition(); std::vector<SgNode*> ifExps; ifExps = NodeQuery::querySubTree(mainDef, V_SgIfStmt); for (int i = 0; i < ifExps.size(); i++) { getIfConds(isSgIfStmt(ifExps[i]), isSgScopeStatement(mainDef)); } std::vector<SgNode*> assignNodes = NodeQuery::querySubTree(mainDef, V_SgVariableDeclaration); std::cout << assignNodes.size() << " nodes found" << std::endl; std::vector<SgBinaryOp*> bin_ops; std::vector<SgUnaryOp*> un_ops; std::vector<SgNode*> other; std::vector<SgExpression*> results; for (std::vector<SgNode*>::iterator i = assignNodes.begin(); i != assignNodes.end(); i++) { SgVariableDeclaration* vdecl = isSgVariableDeclaration(*i); SgInitializedNamePtrList vlst = vdecl->get_variables(); SgInitializedName* initName = isSgInitializedName((*(vlst.begin()))); SgExpression* exp = isSgAssignInitializer(initName->get_initializer())->get_operand(); std::cout << exp->class_name() << std::endl; if (!isSgFunctionCallExp(exp)) { getExps(exp, isSgInitializedName(*i), results, 0); std::cout << "prefixes" << std::endl; for (int j = 0; j < prefixes.size(); j++) { SgExprStatement* expSt = SageBuilder::buildExprStatement_nfi(prefixes[j]); SageInterface::insertStatement(isSgVariableDeclaration(*i),expSt,true); std::cout << prefixes[j]->class_name() << std::endl; } std::cout << "results" << std::endl; for (int j = 0; j < results.size(); j++) { std::cout << results[j]->class_name() << std::endl; } std::cout << "postfixes" << std::endl; for (int j = 0; j < postfixes.size(); j++) { SgExprStatement* expSt = SageBuilder::buildExprStatement_nfi(postfixes[j]); SageInterface::insertStatement(isSgVariableDeclaration(*i),expSt,false); std::cout << postfixes[j]->class_name() << std::endl; } replaceExps(exp,vdecl); simplifyExps(exp); } } backend(proj); return 0; }
virtual void visit(SgNode* n) { #if 0 // Debugging code if (!isSgInitializedName(n)) n->unparseToString(); #endif SgFunctionCallExp* n2 = isSgFunctionCallExp(n); if (n2) { calls_to_inline.push_back(n2); } }
virtual void visit(SgNode *node) { /*override*/ SgFunctionCallExp *fcall = isSgFunctionCallExp(node); SgFunctionDeclaration *fdecl = fcall ? fcall->getAssociatedFunctionDeclaration() : NULL; std::string fname = fdecl ? fdecl->get_qualified_name().getString() : ""; if (SageInterface::is_Java_language()) { if (0==fname.compare("System.getenv")) { found.push_back(fcall); CodeProperties::message(std::cout, fcall, "environment variable is read"); } } else if (0==fname.compare("::getenv")) { found.push_back(fcall); CodeProperties::message(std::cout, fcall, "environment variable is read"); } }
/* * Replace the op_par_loop with respective kernel function */ void OPSource::fixParLoops(SgNode *n) { SgName kernel_name; SgFunctionCallExp *fn = isSgFunctionCallExp(n); if(fn != NULL) { string fn_name = fn->getAssociatedFunctionDeclaration()->get_name().getString(); if(fn_name.compare("op_par_loop_2")==0 || fn_name.compare("op_par_loop_3")==0 || fn_name.compare("op_par_loop_4")==0 || fn_name.compare("op_par_loop_5")==0 || fn_name.compare("op_par_loop_6")==0 || fn_name.compare("op_par_loop_7")==0 || fn_name.compare("op_par_loop_8")==0 || fn_name.compare("op_par_loop_9")==0) { SgExprListExp* exprList = fn->get_args(); SgExpressionPtrList &exprs = exprList->get_expressions(); SgFunctionRefExp* varExp = isSgFunctionRefExp(exprs[0]); if(varExp != NULL) { kernel_name = varExp->get_symbol()->get_name(); } exprs.erase(exprs.begin()); SgExpressionPtrList::iterator it = exprs.begin() + op_par_loop_args::num_params - 1; for(; it != exprs.end(); it += op_argument::num_params) { *it = buildCastExp( *it, buildPointerType(SgClassType::createType( buildStructDeclaration("op_dat<void>"))) ); } // Inject Name exprs.insert(exprs.begin(), buildStringVal(kernel_name)); // Fetch the declaration SgName name = SgName("op_par_loop_") + kernel_name; SgFunctionDeclaration *funcDecl = cudaFunctionDeclarations[kernel_name]; if(funcDecl) { SgFunctionRefExp* ref = isSgFunctionRefExp(fn->get_function()); SgFunctionSymbol *symbol = ref->get_symbol(); symbol->set_declaration(funcDecl); ref->set_symbol(symbol); fn->set_function(ref); } } } }
void pCFGIterator::filterSendRecv(const pCFGNode& pcfgn, set<unsigned int>& blockedPSets, set<unsigned int>& sendPSets, set<unsigned int>& recvPSets) { set<unsigned int>::iterator it; for(it = blockedPSets.begin(); it != blockedPSets.end(); it++) { const DataflowNode& dfnode = pcfgn.getCurNode(*it); SgNode* sgn = dfnode.getNode(); Function callee(isSgFunctionCallExp(sgn)); if(callee.get_name().getString() == "MPI_Send") { sendPSets.insert(*it); } else if(callee.get_name().getString() == "MPI_Recv") { recvPSets.insert(*it); } } }
void visit(SgNode *n) { switch (n->variantT()) { case V_SgStatementExpression: reportError("GNU extension 'statement expression' is not allowed.", n); break; case V_SgFunctionCallExp: { SgFunctionCallExp *FCE = isSgFunctionCallExp(n); SgFunctionDeclaration *calleeFD = FCE->getAssociatedFunctionDeclaration(); if (!calleeFD) { reportError("calls through function pointers are not allowed.", n); } break; } default: break; } }
ParseTree * ParseTree::extractParseTree( SgExpression * exp, const PolyhedricAnnotation::FunctionPolyhedralProgram & function_program, PolyGraph * polygraph, std::string isl_domain, unsigned stmt_id ) { SgBinaryOp * bin_op = isSgBinaryOp(exp); SgUnaryOp * una_op = isSgUnaryOp(exp); SgConditionalExp * cond_exp = isSgConditionalExp(exp); SgFunctionCallExp * func_call = isSgFunctionCallExp(exp); ParseTree * c1 = NULL; ParseTree * c2 = NULL; ParseTree * c3 = NULL; unsigned variant = exp->variantT(); if (isSgPntrArrRefExp(exp)) bin_op = NULL; if (bin_op != NULL) { c1 = extractParseTree(bin_op->get_lhs_operand_i(), function_program, polygraph, isl_domain, stmt_id); c2 = extractParseTree(bin_op->get_rhs_operand_i(), function_program, polygraph, isl_domain, stmt_id); } else if (una_op != NULL) { c1 = extractParseTree(una_op->get_operand_i(), function_program, polygraph, isl_domain, stmt_id); } else if (cond_exp != NULL) { c1 = extractParseTree(cond_exp->get_conditional_exp(), function_program, polygraph, isl_domain, stmt_id); c2 = extractParseTree(cond_exp->get_true_exp(), function_program, polygraph, isl_domain, stmt_id); c3 = extractParseTree(cond_exp->get_false_exp(), function_program, polygraph, isl_domain, stmt_id); } else if (func_call != NULL) { std::vector<SgExpression *> args = func_call->get_args()->get_expressions(); ROSE_ASSERT(args.size() == 1); c1 = extractParseTree(args[0], function_program, polygraph, isl_domain, stmt_id); } else { return new Data(polygraph, exp, function_program, isl_domain); } return new Operator(polygraph, variant, c1, c2, c3); }
virtual void visit(SgNode * n) { switch (n->variantT()) { case V_SgFunctionDeclaration: { SgFunctionDeclaration * func_decl = isSgFunctionDeclaration(n); ROSE_ASSERT(func_decl != NULL); std::string func_name = func_decl->get_name().getString(); // std::cout << "Found SgFunctionDeclaration: " << func_name << std::endl; if (func_name == "caller") p_caller = func_decl; if (func_name == "kernel") p_kernel = func_decl; break; } case V_SgForStatement: { SgForStatement * for_stmt = isSgForStatement(n); ROSE_ASSERT(for_stmt != NULL); // std::cout << "Found SgForStatement." << std::endl; p_for_stmts.push_back(for_stmt); break; } case V_SgFunctionCallExp: { SgFunctionCallExp * func_call = isSgFunctionCallExp(n); ROSE_ASSERT(func_call != NULL); SgFunctionRefExp * func_ref = isSgFunctionRefExp(func_call->get_function()); ROSE_ASSERT(func_ref != NULL); // std::cout << "Found SgFunctionCallExp: " << func_ref->getAssociatedFunctionDeclaration ()->get_name().getString() << std::endl; if (func_ref->getAssociatedFunctionDeclaration()->get_name().getString() == "kernel") p_kernel_call_site = func_call; break; } case V_SgSourceFile: // fix the file suffix, Liao 12/29/2010 { SgSourceFile * sfile = isSgSourceFile (n); ROSE_ASSERT (sfile != NULL); sfile->set_Cuda_only(true); } default:{} } }
bool isHtThreadControlStmt(SgStatement *S) { SgExprStatement *es = isSgExprStatement(S); SgFunctionCallExp *fce = 0; if (es && (fce = isSgFunctionCallExp(es->get_expression()))) { SgFunctionDeclaration *calleeFD = fce->getAssociatedFunctionDeclaration(); std::string fname = calleeFD->get_name().getString(); size_t pos = 0; if (fname == "WriteMemPause" || fname == "ReadMemPause" || fname == "HtBarrier" || (((pos = fname.find("SendCall_")) != std::string::npos /* || (pos = fname.find("SendCallFork_")) != std::string::npos */ || (pos = fname.find("SendReturn_")) != std::string::npos || (pos = fname.find("RecvReturnJoin_")) != std::string::npos) && pos == 0)) { return true; } } return false; }
bool findCallsWithFuncArgs(SgNode *node, string &str) { SgExprStatement *statement; if (statement = isSgExprStatement(node)) { SgFunctionCallExp *call_exp; if (call_exp = isSgFunctionCallExp(statement->get_the_expr())) { m_nodes.clear(); m_nodes.insert(call_exp); m_domain.expand(&m_nodes, QRQueryDomain::all_children); m_domain.getNodes()->erase(call_exp); NodeQuery::VariantVector vector(V_SgFunctionCallExp); QRQueryOpVariant op(vector); op.performQuery(&m_domain, &m_range); unsigned hits = m_range.countRange(); if (hits) { sprintf(m_buffer, "%d", hits); str = m_buffer; return true; } } } return false; }
bool FortranAnalysis::matchRegionAssignment(SgExprStatement * expr_stmt) { SgBinaryOp * bin_op = isSgBinaryOp(expr_stmt->get_expression()); if (bin_op == NULL) return false; SgFunctionCallExp * fcall = isSgFunctionCallExp(bin_op->get_rhs_operand()); if (fcall == NULL) return false; SgFunctionRefExp * fref = isSgFunctionRefExp(fcall->get_function()); if (fref == NULL) return false; SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin(); std::string name = fref->get_symbol()->get_name().getString(); if (name == "interior" && it != fcall->get_args()->get_expressions().end()) { SgVarRefExp * var = isSgVarRefExp(*it); if (var == NULL) return false; AstTextAttribute * attr = (AstTextAttribute *) var->get_symbol()->getAttribute("dummy_attr"); if (attr == NULL) return false; if (attr->toString() != "DUMMY_ARRAY_ARG") return false; } return true; }
int main( int argc, char* argv[] ) { // Initialize and check compatibility. See rose::initialize ROSE_INITIALIZE; SgProject* project = frontend(argc,argv); AstTests::runAllTests(project); #if 0 // Output the graph so that we can see the whole AST graph, for debugging. generateAstGraph(project, 4000); #endif #if 1 printf ("Generate the dot output of the SAGE III AST \n"); generateDOT ( *project ); printf ("DONE: Generate the dot output of the SAGE III AST \n"); #endif // There are lots of way to write this, this is one simple approach; get all the function calls. std::vector<SgNode*> functionCalls = NodeQuery::querySubTree (project,V_SgFunctionCallExp); // Find the SgFunctionSymbol for snprintf so that we can reset references to "sprintf" to "snprintf" instead. // SgGlobal* globalScope = (*project)[0]->get_globalScope(); SgSourceFile* sourceFile = isSgSourceFile(project->get_fileList()[0]); ROSE_ASSERT(sourceFile != NULL); SgGlobal* globalScope = sourceFile->get_globalScope(); SgFunctionSymbol* snprintf_functionSymbol = globalScope->lookup_function_symbol("snprintf"); ROSE_ASSERT(snprintf_functionSymbol != NULL); // Iterate over the function calls to find the calls to "sprintf" for (unsigned long i = 0; i < functionCalls.size(); i++) { SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(functionCalls[i]); ROSE_ASSERT(functionCallExp != NULL); SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function()); if (functionRefExp != NULL) { SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol(); if (functionSymbol != NULL) { SgName functionName = functionSymbol->get_name(); // printf ("Function being called: %s \n",functionName.str()); if (functionName == "sprintf") { // Now we have something to do! functionRefExp->set_symbol(snprintf_functionSymbol); // Now add the "n" argument SgExprListExp* functionArguments = functionCallExp->get_args(); SgExpressionPtrList & functionArgumentList = functionArguments->get_expressions(); // "sprintf" shuld have exactly 2 arguments (I guess the "..." don't count) printf ("functionArgumentList.size() = %zu \n",functionArgumentList.size()); // ROSE_ASSERT(functionArgumentList.size() == 2); SgExpressionPtrList::iterator i = functionArgumentList.begin(); // printf ("(*i) = %p = %s = %s \n",*i,(*i)->class_name().c_str(),SageInterface::get_name(*i).c_str()); SgVarRefExp* variableRefExp = isSgVarRefExp(*i); ROSE_ASSERT(variableRefExp != NULL); // printf ("variableRefExp->get_type() = %p = %s = %s \n",variableRefExp->get_type(),variableRefExp->get_type()->class_name().c_str(),SageInterface::get_name(variableRefExp->get_type()).c_str()); SgType* bufferType = variableRefExp->get_type(); SgExpression* bufferLengthExpression = NULL; switch(bufferType->variantT()) { case V_SgArrayType: { SgArrayType* arrayType = isSgArrayType(bufferType); bufferLengthExpression = arrayType->get_index(); break; } case V_SgPointerType: { // SgPointerType* pointerType = isSgPointerType(bufferType); SgInitializedName* variableDeclaration = variableRefExp->get_symbol()->get_declaration(); ROSE_ASSERT(variableDeclaration != NULL); SgExpression* initializer = variableDeclaration->get_initializer(); if (initializer != NULL) { SgAssignInitializer* assignmentInitializer = isSgAssignInitializer(initializer); ROSE_ASSERT(assignmentInitializer != NULL); // This is the rhs of the initialization of the pointer (likely a malloc through a cast). // This assumes: buffer = (char*) malloc(bufferLengthExpression); SgExpression* initializationExpression = assignmentInitializer->get_operand(); ROSE_ASSERT(initializationExpression != NULL); SgCastExp* castExp = isSgCastExp(initializationExpression); ROSE_ASSERT(castExp != NULL); SgFunctionCallExp* functionCall = isSgFunctionCallExp(castExp->get_operand()); ROSE_ASSERT(functionCall != NULL); SgExprListExp* functionArguments = isSgExprListExp(functionCall->get_args()); bufferLengthExpression = functionArguments->get_expressions()[0]; ROSE_ASSERT(bufferLengthExpression != NULL); } else { printf ("Initializer not found, so no value for n in snprintf can be computed currently \n"); } break; } default: { printf ("Error: default reached in evaluation of buffer type = %p = %s \n",bufferType,bufferType->class_name().c_str()); ROSE_ASSERT(false); } } ROSE_ASSERT(bufferLengthExpression != NULL); // printf ("bufferLengthExpression = %p = %s = %s \n",bufferLengthExpression,bufferLengthExpression->class_name().c_str(),SageInterface::get_name(bufferLengthExpression).c_str()); // Jump over the first argument, the "n" is defined to be the 2nd argument (the rest are shifted one position). i++; // Build a deep copy of the expression used to define the static buffer (could be any complex expression). SgTreeCopy copy_help; SgExpression* bufferLengthExpression_copy = isSgExpression(bufferLengthExpression->copy(copy_help)); // Insert the "n" for the parameter list to work with "snprintf" instead of "sprintf" functionArgumentList.insert(i,bufferLengthExpression_copy); } } } } return backend(project); }
void CompassAnalyses::VariableNameEqualsDatabaseName::Traversal:: visit(SgNode* node) { if( isSgAssignInitializer(node) != NULL ) assignExp = node; if( isSgAssignOp(node) != NULL ) assignExp = node; SgFunctionCallExp* funcCall = isSgFunctionCallExp(node); // See if we have a dot expression or arrow expression which // accesses the desired member function in the class we are looking for. if ( funcCall != NULL ) { SgExpression* funcExp = funcCall->get_function(); if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) ) { SgBinaryOp* binOp = isSgBinaryOp(funcExp); SgExpression* rhsOp = binOp->get_rhs_operand(); // SgExpression* lhsOp = binOp->get_lhs_operand(); if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp) ) { // std::cout << "c1\n" ; SgMemberFunctionSymbol* funcSymbol = funcRef->get_symbol(); ROSE_ASSERT(funcSymbol->get_declaration() != NULL); // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C) // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL); if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL) { SgMemberFunctionDeclaration* funcDecl = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration()); ROSE_ASSERT( funcDecl != NULL ); SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope()); SgClassDeclaration* clDecl = isSgClassDeclaration(clDef->get_declaration()); // SgClassDeclaration* clDecl = funcDecl->get_associatedClassDeclaration(); ROSE_ASSERT( clDecl != NULL ); std::string className = clDecl->get_name().getString(); ROSE_ASSERT(funcDecl != NULL); std::string functionName = funcDecl->get_name().getString(); // If the class is the class we are looking for see if the member function // access is to the member function we are interested in. // std::cout << "className = " << className << std::endl; // std::cout << "functionName = " << functionName << std::endl; if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) ) { SgExprListExp* actualArgs = funcCall->get_args(); SgExpressionPtrList& actualExpArgs = actualArgs->get_expressions (); ROSE_ASSERT(actualExpArgs.size() == 1); Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal); ROSE_ASSERT( nodeLst.size() > 0); SgStringVal* actualArg = isSgStringVal(*nodeLst.begin()); ROSE_ASSERT(actualArg != NULL); std::string stringArg = actualArg->get_value(); std::cout << "arg:" << stringArg << std::endl; std::string varName; // SgInitializedName* initName = NULL; if ( SgAssignInitializer* assignInit = isSgAssignInitializer(assignExp) ) { SgInitializedName* initName = isSgInitializedName(assignInit->get_parent()); ROSE_ASSERT(initName != NULL); varName = initName->get_name().getString(); } else { if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) ) { SgExpression* lhsOp = assignOp->get_lhs_operand(); SgVarRefExp* varRef = isSgVarRefExp(lhsOp); ROSE_ASSERT(varRef!=NULL); SgVariableSymbol* varSymbol = varRef->get_symbol(); ROSE_ASSERT(varSymbol != NULL); SgInitializedName* initName = varSymbol->get_declaration(); varName = initName->get_name().getString(); } } if (varName != "") { // we are only interested in the part of the argument after the last ":" // Database scopes in ALE3D are separated by ":" size_t posCol = stringArg.find_last_of(':'); if (posCol != std::string::npos) stringArg = stringArg.substr(posCol+1); //Find violations to the rule if ( stringArg != varName) { output->addOutput(new CheckerOutput(assignExp)); std::cout << "violation" << varName << std::endl; } else { std::cout << "non=violation" << varName << std::endl; } } } } } } } } // End of the visit function.
void ProcTraversal::visit(SgNode *node) { if (isSgFunctionDeclaration(node)) { SgFunctionDeclaration *decl = isSgFunctionDeclaration(node); if (decl->get_definition() != NULL) { /* collect statistics */ //AstNumberOfNodesStatistics anons; //anons.traverse(decl, postorder); //original_ast_nodes += anons.get_numberofnodes(); //original_ast_statements += anons.get_numberofstatements(); /* do the real work */ Procedure *proc = new Procedure(); proc->procnum = procnum++; proc->decl = decl; proc->funcsym = isSgFunctionSymbol(decl->get_symbol_from_symbol_table()); if (proc->funcsym == NULL) { #if 0 std::cout << std::endl << "*** NULL function symbol for declaration " << decl->unparseToString() << std::endl << "symbol: " << (void *) decl->get_symbol_from_symbol_table() << (decl->get_symbol_from_symbol_table() != NULL ? decl->get_symbol_from_symbol_table()->class_name() : "") << std::endl << "first nondef decl: " << (void *) decl->get_firstNondefiningDeclaration() << " sym: " << (decl->get_firstNondefiningDeclaration() != NULL ? (void *) decl->get_firstNondefiningDeclaration() ->get_symbol_from_symbol_table() : (void *) NULL) << std::endl; #endif if (decl->get_firstNondefiningDeclaration() != NULL) { proc->funcsym = isSgFunctionSymbol(decl ->get_firstNondefiningDeclaration() ->get_symbol_from_symbol_table()); } } assert(proc->funcsym != NULL); // GB (2008-05-14): We need two parameter lists: One for the names of the // variables inside the function definition, which is // decl->get_parameterList(), and one that contains any default arguments // the function might have. The default arguments are supposedly // associated with the first nondefining declaration. proc->params = decl->get_parameterList(); SgDeclarationStatement *fndstmt = decl->get_firstNondefiningDeclaration(); SgFunctionDeclaration *fnd = isSgFunctionDeclaration(fndstmt); if (fnd != NULL && fnd != decl) proc->default_params = fnd->get_parameterList(); else proc->default_params = proc->params; SgMemberFunctionDeclaration *mdecl = isSgMemberFunctionDeclaration(decl); if (mdecl) { proc->class_type = isSgClassDefinition(mdecl->get_scope()); std::string name = proc->class_type->get_mangled_name().str(); name += "::"; name += decl->get_name().str(); std::string mname = proc->class_type->get_mangled_name().str(); mname += "::"; mname += decl->get_mangled_name().str(); proc->memberf_name = name; proc->mangled_memberf_name = mname; proc->name = decl->get_name().str(); proc->mangled_name = decl->get_mangled_name().str(); // GB (2008-05-26): Computing a single this symbol for each // procedure. Thus, this symbol can also be compared by pointer // equality (as is the case for all other symbols). While we're at it, // we also build a VarRefExp for this which can be used everywhere the // this pointer occurs. proc->this_type = Ir::createPointerType( proc->class_type->get_declaration()->get_type()); proc->this_sym = Ir::createVariableSymbol("this", proc->this_type); proc->this_exp = Ir::createVarRefExp(proc->this_sym); } else { proc->name = decl->get_name().str(); proc->mangled_name = decl->get_mangled_name().str(); proc->class_type = NULL; proc->memberf_name = proc->mangled_memberf_name = ""; proc->this_type = NULL; proc->this_sym = NULL; proc->this_exp = NULL; // GB (2008-07-01): Better resolution of calls to static functions. // This only makes sense for non-member functions. SgStorageModifier &sm = (fnd != NULL ? fnd : decl)->get_declarationModifier().get_storageModifier(); proc->isStatic = sm.isStatic(); // Note that we query the first nondefining declaration for the // static modifier, but we save the file of the *defining* // declaration. This is because the first declaration might be in // some header file, but for call resolution, the actual source // file with the definition is relevant. // Trace back to the enclosing file node. The definition might be // included in foo.c from bar.c, in which case the Sg_File_Info // would refer to bar.c; but for function call resolution, foo.c is // the relevant file. SgNode *p = decl->get_parent(); while (p != NULL && !isSgFile(p)) p = p->get_parent(); proc->containingFile = isSgFile(p); } proc_map.insert(std::make_pair(proc->name, proc)); mangled_proc_map.insert(std::make_pair(proc->mangled_name, proc)); std::vector<SgVariableSymbol* >* arglist = new std::vector<SgVariableSymbol* >(); SgVariableSymbol *this_var = NULL, *this_temp_var = NULL; if (mdecl || decl->get_parameterList() != NULL && !decl->get_parameterList()->get_args().empty()) { proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum); if (mdecl) { // GB (2008-05-26): We now compute the this pointer right at the // beginning of building the procedure. // this_var = Ir::createVariableSymbol("this", this_type); this_var = proc->this_sym; // std::string varname // = std::string("$") + proc->name + "$this"; // this_temp_var = Ir::createVariableSymbol(varname, proc->this_type); this_temp_var = global_this_variable_symbol; ParamAssignment* paramAssignment = Ir::createParamAssignment(this_var, this_temp_var); proc->arg_block->statements.push_back(paramAssignment); arglist->push_back(this_var); if (proc->name.find('~') != std::string::npos) { arglist->push_back(this_temp_var); } } SgInitializedNamePtrList params = proc->params->get_args(); SgInitializedNamePtrList::const_iterator i; #if 0 int parnum = 0; for (i = params.begin(); i != params.end(); ++i) { SgVariableSymbol *i_var = Ir::createVariableSymbol(*i); std::stringstream varname; // varname << "$" << proc->name << "$arg_" << parnum++; SgVariableSymbol* var = Ir::createVariableSymbol(varname.str(),(*i)->get_type()); proc->arg_block->statements.push_back(Ir::createParamAssignment(i_var, var)); arglist->push_back(i_var); } #else // GB (2008-06-23): Trying to replace all procedure-specific argument // variables by a global list of argument variables. This means that at // this point, we do not necessarily need to build a complete list but // only add to the CFG's argument list if it is not long enough. size_t func_params = params.size(); size_t global_args = global_argument_variable_symbols.size(); std::stringstream varname; while (global_args < func_params) { varname.str(""); varname << "$tmpvar$arg_" << global_args++; SgVariableSymbol *var = Ir::createVariableSymbol(varname.str(), global_unknown_type); program->global_map[varname.str()] = std::make_pair(var, var->get_declaration()); global_argument_variable_symbols.push_back(var); } // now create the param assignments size_t j = 0; for (i = params.begin(); i != params.end(); ++i) { SgVariableSymbol *i_var = Ir::createVariableSymbol(params[j]); SgVariableSymbol *var = global_argument_variable_symbols[j]; j++; proc->arg_block->statements.push_back( Ir::createParamAssignment(i_var, var)); arglist->push_back(i_var); } #if 0 // replace the arglist allocated above by the new one; this must be // fixed for this pointers! delete arglist; arglist = &global_argument_variable_symbols; #endif #endif } else { proc->arg_block = NULL; } /* If this is a constructor, call default constructors * of all base classes. If base class constructors are * called manually, these calls will be removed later. */ if (mdecl && strcmp(mdecl->get_name().str(), proc->class_type->get_declaration()->get_name().str()) == 0 && proc->class_type != NULL) { SgBaseClassPtrList::iterator base; for (base = proc->class_type->get_inheritances().begin(); base != proc->class_type->get_inheritances().end(); ++base) { SgClassDeclaration* baseclass = (*base)->get_base_class(); SgVariableSymbol *lhs = Ir::createVariableSymbol("$tmpvar$" + baseclass->get_name(), baseclass->get_type()); program->global_map["$tmpvar$" + baseclass->get_name()] = std::make_pair(lhs, lhs->get_declaration()); SgMemberFunctionDeclaration* fd=get_default_constructor(baseclass); assert(fd); SgType* basetype=baseclass->get_type(); assert(basetype); SgConstructorInitializer *sci = Ir::createConstructorInitializer(fd,basetype); ArgumentAssignment* a = Ir::createArgumentAssignment(lhs, sci); proc->arg_block->statements.push_back(a); // std::string this_called_varname // = std::string("$") + baseclass->get_name() + "$this"; SgVariableSymbol *this_called_var // = Ir::createVariableSymbol(this_called_varname, // baseclass->get_type()); = global_this_variable_symbol; ReturnAssignment* this_ass = Ir::createReturnAssignment(this_var, this_called_var); proc->arg_block->statements.push_back(this_ass); } } if (mdecl && mdecl->get_CtorInitializerList() != NULL && !mdecl->get_CtorInitializerList()->get_ctors().empty()) { SgInitializedNamePtrList cis = mdecl->get_CtorInitializerList()->get_ctors(); SgInitializedNamePtrList::const_iterator i; if (proc->arg_block == NULL) { proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum); } for (i = cis.begin(); i != cis.end(); ++i) { SgVariableSymbol* lhs = Ir::createVariableSymbol(*i); SgAssignInitializer *ai = isSgAssignInitializer((*i)->get_initializer()); SgConstructorInitializer *ci = isSgConstructorInitializer((*i)->get_initializer()); /* TODO: other types of initializers */ if (ai) { SgClassDeclaration *class_decl = proc->class_type->get_declaration(); // GB (2008-05-26): We now compute the this pointer right at the // beginning of building the procedure. // SgVarRefExp* this_ref // = Ir::createVarRefExp("this", // Ir::createPointerType(class_decl->get_type())); SgVarRefExp* this_ref = proc->this_exp; SgArrowExp* arrowExp = Ir::createArrowExp(this_ref,Ir::createVarRefExp(lhs)); // GB (2008-03-17): We need to handle function calls in // initializers. In order to be able to build an argument // assignment, we need to know the function's return variable, so // the expression labeler must be called on it. The expression // number is irrelevant, however, as it does not appear in the // return variable. if (isSgFunctionCallExp(ai->get_operand_i())) { #if 0 ExprLabeler el(0 /*expnum*/); el.traverse(ai->get_operand_i(), preorder); // expnum = el.get_expnum(); #endif // GB (2008-06-25): There is now a single global return // variable. This may or may not mean that we can simply ignore // the code above. I don't quite understand why this labeling // couldn't be done later on, and where its result was used. } ArgumentAssignment* argumentAssignment = Ir::createArgumentAssignment(arrowExp,ai->get_operand_i()); proc->arg_block->statements.push_back(argumentAssignment); } else if (ci) { /* if this is a call to a base class's * constructor, remove the call we generated * before */ SgStatement* this_a = NULL; SgClassDeclaration* cd = ci->get_class_decl(); std::deque<SgStatement *>::iterator i; for (i = proc->arg_block->statements.begin(); i != proc->arg_block->statements.end(); ++i) { ArgumentAssignment* a = dynamic_cast<ArgumentAssignment *>(*i); if (a && isSgConstructorInitializer(a->get_rhs())) { SgConstructorInitializer* c = isSgConstructorInitializer(a->get_rhs()); std::string c_decl_name = c->get_class_decl()->get_name().str(); std::string cd_name = cd->get_name().str(); // if (c->get_class_decl()->get_name() == cd->get_name()) { if (c_decl_name == cd_name) { #if 0 // erase the following assignment // of the this pointer as well this_a = *proc->arg_block->statements.erase(i+1); proc->arg_block->statements.erase(i); #endif // GB (2008-03-28): That's an interesting piece of code, but // it might be very mean to iterators. At least it is hard to // see whether it is correct. So let's try it like this: // erase i; we get an iterator back, which refers to the next // element. Save that element as this_a, and then erase. std::deque<SgStatement *>::iterator this_pos; this_pos = proc->arg_block->statements.erase(i); this_a = *this_pos; proc->arg_block->statements.erase(this_pos); // Good. Looks like this fixed a very obscure bug. break; } } } /* now add the initialization */ proc->arg_block->statements.push_back(Ir::createArgumentAssignment(lhs, ci)); if (this_a != NULL) proc->arg_block->statements.push_back(this_a); } } } proc->entry = new CallBlock(node_id++, START, proc->procnum, new std::vector<SgVariableSymbol *>(*arglist), (proc->memberf_name != "" ? proc->memberf_name : proc->name)); proc->exit = new CallBlock(node_id++, END, proc->procnum, new std::vector<SgVariableSymbol *>(*arglist), (proc->memberf_name != "" ? proc->memberf_name : proc->name)); proc->entry->partner = proc->exit; proc->exit->partner = proc->entry; proc->entry->call_target = Ir::createFunctionRefExp(proc->funcsym); proc->exit->call_target = Ir::createFunctionRefExp(proc->funcsym); /* In constructors, insert an assignment $A$this = this * at the end to make sure that the 'this' pointer can be * passed back to the calling function uncobbled. */ proc->this_assignment = NULL; if (mdecl) { SgMemberFunctionDeclaration* cmdecl = isSgMemberFunctionDeclaration(mdecl->get_firstNondefiningDeclaration()); // if (cmdecl && cmdecl->get_specialFunctionModifier().isConstructor()) { proc->this_assignment = new BasicBlock(node_id++, INNER, proc->procnum); ReturnAssignment* returnAssignment = Ir::createReturnAssignment(this_temp_var, this_var); proc->this_assignment->statements.push_back(returnAssignment); add_link(proc->this_assignment, proc->exit, NORMAL_EDGE); // } } std::stringstream varname; // varname << "$" << proc->name << "$return"; // proc->returnvar = Ir::createVariableSymbol(varname.str(), // decl->get_type()->get_return_type()); proc->returnvar = global_return_variable_symbol; procedures->push_back(proc); if(getPrintCollectedFunctionNames()) { std::cout << (proc->memberf_name != "" ? proc->memberf_name : proc->name) << " " /*<< proc->decl << std::endl*/; } if (proc->arg_block != NULL) { proc->arg_block->call_target = Ir::createFunctionRefExp(proc->funcsym); } // delete arglist; } } }
InheritedAttribute visitorTraversal::evaluateInheritedAttribute(SgNode* n, InheritedAttribute inheritedAttribute) { Sg_File_Info* s = n->get_startOfConstruct(); Sg_File_Info* e = n->get_endOfConstruct(); Sg_File_Info* f = n->get_file_info(); for(int x=0; x < inheritedAttribute.depth; ++x) { printf(" "); } if(s != NULL && e != NULL && !isSgLabelStatement(n)) { printf ("%s (%d, %d, %d)->(%d, %d): %s",n->sage_class_name(),s->get_file_id()+1,s->get_raw_line(),s->get_raw_col(),e->get_raw_line(),e->get_raw_col(), verbose ? n->unparseToString().c_str() : "" ); if(isSgAsmDwarfConstruct(n)) { printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str()); } SgExprStatement * exprStmt = isSgExprStatement(n); if(exprStmt != NULL) { printf(" [expr type: %s]", exprStmt->get_expression()->sage_class_name()); SgFunctionCallExp * fcall = isSgFunctionCallExp(exprStmt->get_expression()); if(fcall != NULL) { SgExpression * funcExpr = fcall->get_function(); if(funcExpr != NULL) { printf(" [function expr: %s]", funcExpr->class_name().c_str()); } SgFunctionDeclaration * fdecl = fcall->getAssociatedFunctionDeclaration(); if(fdecl != NULL) { printf(" [called function: %s]", fdecl->get_name().str()); } } } if(isSgFunctionDeclaration(n)) { printf(" [declares function: %s]", isSgFunctionDeclaration(n)->get_name().str()); } SgStatement * sgStmt = isSgStatement(n); if(sgStmt != NULL) { printf(" [scope: %s, %p]", sgStmt->get_scope()->sage_class_name(), sgStmt->get_scope()); } //SgLabelStatement * lblStmt = isSgLabelStatement(n); //if(lblStmt != NULL) { // SgStatement * lblStmt2 = lblStmt->get_statement(); //} } else if (f != NULL) { SgInitializedName * iname = isSgInitializedName(n); if(iname != NULL) { SgType* inameType = iname->get_type(); printf("%s (%d, %d, %d): %s [type: %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(),n->unparseToString().c_str(),inameType->class_name().c_str()); SgDeclarationStatement * ds = isSgDeclarationStatement(iname->get_parent()); if(ds != NULL) { if(ds->get_declarationModifier().get_storageModifier().isStatic()) { printf(" static"); } } SgArrayType * art = isSgArrayType(iname->get_type()); if(art != NULL) { printf(" %d", art->get_rank()); } printf("]"); if(isSgAsmDwarfConstruct(n)) { printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str()); } } else { printf("%s (%d, %d, %d): %s", n->sage_class_name(),f->get_file_id()+1,f->get_raw_line(),f->get_raw_col(), verbose ? n->unparseToString().c_str() : ""); } } else { printf("%s : %s", n->sage_class_name(), verbose ? n->unparseToString().c_str() : ""); if(isSgAsmDwarfConstruct(n)) { printf(" [DWARF construct name: %s]", isSgAsmDwarfConstruct(n)->get_name().c_str()); } } printf(" succ# %lu", n->get_numberOfTraversalSuccessors()); printf("\n"); return InheritedAttribute(inheritedAttribute.depth+1); }
int main(int argc, char **argv) { SgProject *project = frontend(argc, argv); // Instantiate a class hierarchy wrapper. ClassHierarchyWrapper classHierarchy( project ); std::list<SgNode *> nodes2 = NodeQuery::querySubTree(project, V_SgVariableDefinition); for (std::list<SgNode *>::iterator it = nodes2.begin(); it != nodes2.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgVariableDefinition *varDefn = isSgVariableDefinition(n); ROSE_ASSERT(varDefn != NULL); std::cout << "Var defn: " << varDefn->unparseToCompleteString() << std::endl; } std::list<SgNode *> nodes1 = NodeQuery::querySubTree(project, V_SgVariableDeclaration); for (std::list<SgNode *>::iterator it = nodes1.begin(); it != nodes1.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgVariableDeclaration *varDecl = isSgVariableDeclaration(n); ROSE_ASSERT(varDecl != NULL); SgInitializedNamePtrList &variables = varDecl->get_variables(); SgInitializedNamePtrList::iterator varIter; for (varIter = variables.begin(); varIter != variables.end(); ++varIter) { SgNode *var = *varIter; ROSE_ASSERT(var != NULL); SgInitializedName *initName = isSgInitializedName(var); ROSE_ASSERT(initName != NULL); if ( isSgClassType(initName->get_type()) ) { SgClassType *classType = isSgClassType(initName->get_type()); ROSE_ASSERT(classType != NULL); SgDeclarationStatement *declStmt = classType->get_declaration(); ROSE_ASSERT(declStmt != NULL); SgClassDeclaration *classDeclaration = isSgClassDeclaration(declStmt); ROSE_ASSERT(classDeclaration != NULL); // std::cout << "From var decl got: " << classDeclaration->unparseToCompleteString() << std::endl; SgClassDefinition *classDefinition = classDeclaration->get_definition(); if ( classDefinition != NULL ) { std::cout << "From var decl got: " << classDefinition->unparseToCompleteString() << std::endl; } } } } std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgClassDeclaration); for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgClassDeclaration *classDeclaration1 = isSgClassDeclaration(n); ROSE_ASSERT(classDeclaration1 != NULL); SgDeclarationStatement *definingDecl = classDeclaration1->get_definingDeclaration(); if ( definingDecl == NULL ) continue; SgClassDeclaration *classDeclaration = isSgClassDeclaration(definingDecl); ROSE_ASSERT(classDeclaration != NULL); SgClassDefinition *classDefinition = classDeclaration->get_definition(); ROSE_ASSERT(classDefinition != NULL); std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl; SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; } } #if 0 #if 0 std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgClassDefinition); for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgClassDefinition *classDefinition = isSgClassDefinition(n); ROSE_ASSERT(classDefinition != NULL); std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl; SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; } } #else // Collect all function/method invocations. std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgFunctionCallExp); unsigned int numCallSites = 0; unsigned int numMonomorphicCallSites = 0; unsigned int numPossibleResolutions = 0; // Visit each call site. for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgFunctionCallExp *functionCallExp = isSgFunctionCallExp(n); ROSE_ASSERT(functionCallExp != NULL); // We are only interested in examining method invocations. bool isDotExp = false; if ( !isMethodCall(functionCallExp, isDotExp) ) continue; numCallSites++; // Certainly can be resolved to the static method. numPossibleResolutions++; if ( isDotExp ) { // If this is a dot expression (i.e., a.foo()), we can // statically determine its type. numMonomorphicCallSites++; continue; } // Retrieve the static function declaration. SgFunctionDeclaration *functionDeclaration = getFunctionDeclaration(functionCallExp); // Ensure it is actually a method declaration. SgMemberFunctionDeclaration *memberFunctionDeclaration = isSgMemberFunctionDeclaration(functionDeclaration); ROSE_ASSERT(memberFunctionDeclaration != NULL); unsigned int numOverridesForMethod = 0; if ( ( isVirtual(functionDeclaration) ) || ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) { SgClassDefinition *classDefinition = isSgClassDefinition(memberFunctionDeclaration->get_scope()); ROSE_ASSERT(classDefinition != NULL); SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; // Iterate over all of the methods defined in this subclass. SgDeclarationStatementPtrList &decls = subclass->get_members(); for (SgDeclarationStatementPtrList::iterator declIter = decls.begin(); declIter != decls.end(); ++declIter) { SgDeclarationStatement *declStmt = *declIter; ROSE_ASSERT(declStmt != NULL); SgMemberFunctionDeclaration *method = isSgMemberFunctionDeclaration(declStmt); if ( method == NULL ) { continue; } // Determine whether subclass of the class defining this // method overrides the method. if ( methodOverridesVirtualMethod(method, memberFunctionDeclaration) ) { numOverridesForMethod++; } } } if ( numOverridesForMethod == 0 ) numMonomorphicCallSites++; numPossibleResolutions += numOverridesForMethod; std::cout << "Method invocation has " << numOverridesForMethod + 1 << " possible resolutions " << std::endl; std::cout << functionCallExp->unparseToCompleteString() << std::endl; } } #endif #endif return 0; }
void VirtualFunctionAnalysis::run() { printf ("In VirtualFunctionAnalysis::run() \n"); vector<SgExpression*> callSites = SageInterface::querySubTree<SgExpression> (project, V_SgFunctionCallExp); printf ("In VirtualFunctionAnalysis::run(): after querySubTree on V_SgFunctionCallExp \n"); vector<SgExpression*> constrs = SageInterface::querySubTree<SgExpression> (project, V_SgConstructorInitializer); printf ("In VirtualFunctionAnalysis::run(): callSites.insert() \n"); callSites.insert(callSites.end(), constrs.begin(), constrs.end()); printf ("DONE: VirtualFunctionAnalysis::run(): callSites.insert() \n"); // Not all SgFunctionCallExp or SgConstructorInitialize nodes appear in functions--some are also in templates (for // classes or functions) and we don't want to process those. Templates are not really part of a control flow graph or // call graph until after they're instantiated. for (vector<SgExpression*>::iterator csi=callSites.begin(); csi!=callSites.end(); ++csi) { if (SgFunctionDeclaration *fdecl = SageInterface::getEnclosingNode<SgFunctionDeclaration>(*csi)) { if (isSgTemplateMemberFunctionDeclaration(fdecl) || isSgTemplateFunctionDeclaration(fdecl)) *csi = NULL; } printf ("In VirtualFunctionAnalysis::run(): loop 1 \n"); } printf ("In VirtualFunctionAnalysis::run(): erase \n"); callSites.erase(std::remove(callSites.begin(), callSites.end(), (SgExpression*)NULL), callSites.end()); printf ("DONE: VirtualFunctionAnalysis::run(): erase \n"); unsigned int index; resolver.clear(); printf ("DONE: VirtualFunctionAnalysis::run(): clear \n"); for(index = 0; index < callSites.size(); index++) { std::vector<SgFunctionDeclaration *> funcs; printf ("In VirtualFunctionAnalysis::run(): getPropertiesForExpression() \n"); CallTargetSet::getPropertiesForExpression(callSites[index], classHierarchy, funcs); //Virtual Function if(isSgFunctionCallExp(callSites[index]) && funcs.size() > 1 ) funcs.clear(); resolver[callSites[index]] = funcs; printf ("In VirtualFunctionAnalysis::run(): loop 2 \n"); } printf ("In VirtualFunctionAnalysis::run(): PtrAliasAnalysis::run() \n"); PtrAliasAnalysis::run(); printf ("DONE: VirtualFunctionAnalysis::run(): PtrAliasAnalysis::run() \n"); for(index = 0; index < callSites.size(); index++) { if(resolver.at(callSites[index]).size() == 0 ) { std::vector<SgFunctionDeclaration *> funcs; CallTargetSet::getPropertiesForExpression(callSites[index], classHierarchy, funcs); resolver[callSites[index]] = funcs; } printf ("In VirtualFunctionAnalysis::run(): loop 3 \n"); } isExecuted = true; printf ("Leaving VirtualFunctionAnalysis::run() \n"); }
// on other nodes lrRecord (lrRecord &parent, SgNode* n) { SgBinaryOp* binOp; SgUnaryOp* unOp; SgFunctionCallExp* funcCall; //SgPntrArrRefExp* arrRef; char typeStr[100]; // if this node is on the read, write or read-write side of an assignment operation, set its access appropriately if(parent.readSubtree == n) access = readAccess; else if(n == parent.writeSubtree) access = writeAccess; else if(n == parent.rwSubtree) access = rwAccess; else access = parent.access; if((binOp = isSgBinaryOp(n))) { // writeSubtree = readSubtree if(isSgAssignOp(binOp)) { writeSubtree = binOp->get_lhs_operand(); readSubtree = binOp->get_rhs_operand(); rwSubtree = (void*)NULL; strcpy(typeStr, "SgAssignOp"); } // rwSubtree op= readSubtree else if(isSgCompoundAssignOp(binOp)) { rwSubtree = binOp->get_lhs_operand(); readSubtree = binOp->get_rhs_operand(); writeSubtree = (void*)NULL; strcpy(typeStr, "Sg*AssignOp"); } else if(isSgPntrArrRefExp(binOp)) { // all the references involved in an array reference, whether they are used to compute the array name // or used in the argument, are read-only writeSubtree = (void*)NULL; readSubtree = (void*)NULL; readSubtree.wildMatch(); rwSubtree = (void*)NULL; strcpy(typeStr, "SgPntrArrRefExp"); } else { readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; strcpy(typeStr, "???"); } //printf("SgBinaryNode 0x%x type %s access=%d: %s\n", binOp, typeStr, access, binOp->unparseToString().c_str()); } else if((unOp = isSgUnaryOp(n))) { // unary update operations have only one operand, which is read-write // writeSubtree if(isSgMinusMinusOp(unOp) || isSgPlusPlusOp(unOp)) { writeSubtree = (void*)NULL; readSubtree = (void*)NULL; rwSubtree = unOp->get_operand(); strcpy(typeStr, "Sg**Op"); } // dereference operations have a read-only operand else if(isSgPointerDerefExp(unOp)) { writeSubtree = (void*)NULL; readSubtree = unOp->get_operand(); rwSubtree = (void*)NULL; strcpy(typeStr, "isSgPointerDerefExp"); } else { readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; strcpy(typeStr, "???"); } //printf("SgUnaryNode 0x%x %s access=%d: %s\n", unOp, typeStr, access, unOp->unparseToString().c_str()); } else if((funcCall = isSgFunctionCallExp(n))) { // all the references involved in a function call, whether they are used to compute the function pointer // or used in the argument, are read-only writeSubtree = (void*)NULL; readSubtree = (void*)NULL; readSubtree.wildMatch(); rwSubtree = (void*)NULL; //printf("SgFunctionCall 0x%x access=%d: %s\n", funcCall, access, funcCall->unparseToString().c_str()); } // else, if this is neither a binary, nor unary operation node else { // leave subtree fields of this record as NULL readSubtree = (void*)NULL; writeSubtree = (void*)NULL; rwSubtree = (void*)NULL; //printf("SgNode 0x%x access=%d: %s\n", n, access, n->unparseToString().c_str()); } }
/** Visits AST nodes in post-order. This is function-evaluation order. */ bool FunctionEvaluationOrderTraversal::evaluateSynthesizedAttribute(SgNode* astNode, FunctionCallInheritedAttribute parentAttribute, SynthesizedAttributesList) { SgFunctionCallExp* functionCall = isSgFunctionCallExp(astNode); if (functionCall == NULL) return false; //dummy return value FunctionCallInfo functionCallInfo(functionCall); // Can't lift function call arguments from the following: // 1. For loop test and increment // 2. While loop test // 3. Do-While loop test // 4. Either arms of ternary op // 5. RHS of any short circuit expression // An alternative is to use comma operators and use assignemnt op as done by the original author. // for(;foo(bar());) ==> T i; for(;i=bar();foo(i);) // But using assignement op is not always safe and it requires us to always have a default constructor // There is also an issue when the return type is a reference and we'll have to use & op to get a pointer // but if & op is overloaded we may not get the pointer. // Taking all these in view, I am simpling not lifting such expressions. if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_TEST || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INCREMENT || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_WHILE_CONDITION || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_DO_WHILE_CONDITION) { // ***** FOR UNSAFE TRANSFORMATION ******* //Temporary variables should be declared before the stmt ROSE_ASSERT(isSgStatement(parentAttribute.currentScope)); functionCallInfo.tempVarDeclarationLocation = isSgStatement(parentAttribute.currentScope); functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; nonNormalizableFunctionCalls.push_back(functionCallInfo); return false; } // In future, if the function call is assured to be side effect free, then we can lift it from short circuit and conditional expressions if(parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_TRUE_ARM || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_CONDITIONAL_EXP_FALSE_ARM || parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_SHORT_CIRCUIT_EXP_RHS){ if(!IsFunctionCallSideEffectFree(functionCall)) { // ***** FOR UNSAFE TRANSFORMATION ******* //Temporary variables should be declared before the stmt ROSE_ASSERT(parentAttribute.lastStatement); functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; nonNormalizableFunctionCalls.push_back(functionCallInfo); return false; } } //Handle for loops (being inside the body of a for loop doesn't need special handling) if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::INSIDE_FOR_INIT) { SgForStatement* forLoop = isSgForStatement(parentAttribute.currentScope); ROSE_ASSERT(forLoop != NULL); //Temporary variables should be declared before the loop functionCallInfo.tempVarDeclarationLocation = forLoop; functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; } else if (parentAttribute.scopeStatus == FunctionCallInheritedAttribute::IN_SAFE_PLACE) { //Assume we're in a basic block. Then just insert right before the current statement ROSE_ASSERT(parentAttribute.scopeStatus = FunctionCallInheritedAttribute::IN_SAFE_PLACE); functionCallInfo.tempVarDeclarationLocation = parentAttribute.lastStatement; functionCallInfo.tempVarDeclarationInsertionMode = FunctionCallInfo::INSERT_BEFORE; } else { //Unhandled condition?! ROSE_ASSERT(false); } normalizableFunctionCalls.push_back(functionCallInfo); return false; //dummy return value }