Пример #1
0
MySynthesizedAttribute
MyTraversal::evaluateRewriteSynthesizedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute,
		SubTreeSynthesizedAttributes synthesizedAttributeList )
{
	MySynthesizedAttribute returnAttribute;

	switch(astNode->variantT())
	{

		case V_SgVarRefExp: {
				cout << " found V_SgVarRefExp " << astNode->unparseToString() <<  endl;
				if(mReplaceVariable) {
					if( ( strcmp( astNode->unparseToString().c_str(), VARIABLE_NAME )==0 ) &&
							( isSgTypeInt(isSgVarRefExp(astNode)->get_type()) )
						) {
						returnAttribute.setVarRefFound( true );
						AstRestructure::unparserReplace( isSgVarRefExp(astNode), "newInt" );
						cout << "   replacing with 'newInt' " << endl;
					}
				}
			} break;

		case V_SgVariableDeclaration: {
				SgVariableDeclaration *varDecl = isSgVariableDeclaration(astNode);
				cout << " found V_SgVariableDeclaration " << astNode->unparseToString() <<  endl;
				// replace only integer variables called "i"
				if( (varDecl->get_traversalSuccessorContainer().size() > 0) &&
                                    isSgInitializedName( varDecl->get_traversalSuccessorContainer()[0]) && 
                                                ( strcmp(isSgInitializedName(varDecl->get_traversalSuccessorContainer()[0])->get_name().str(), VARIABLE_NAME )==0 ) &&
						( isSgTypeInt(isSgInitializedName(varDecl->get_traversalSuccessorContainer()[0])->get_type()) )
					) {
					// found declaration of "int i"
					string newDeclaration("int newInt = i + 100;");
					returnAttribute.insert( varDecl, newDeclaration, HighLevelCollectionTypedefs::LocalScope, HighLevelCollectionTypedefs::AfterCurrentPosition );
					assert( mReplaceVariable==0 ); // if it's true, there is another "int i", and this transformation wont work...
					mReplaceVariable = 1;
					cout << "   inserted: '" << newDeclaration <<"' , starting variable replacement " <<  endl;
				}
			} break;

		default:
			break;
	} // node type

	bool synth = false;
	for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin();
             i!= synthesizedAttributeList.end(); i++ ) {
                if( (*i).getVarRefFound() ) synth = true;
	}
	if( synth ) {
		returnAttribute.setVarRefFound( true );
		if(isSgStatement( astNode )) {
			cout << "   new statement " << " : '" << astNode->unparseToString() << "' " << endl;
			returnAttribute.setVarRefFound( false );
			//if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!?
				returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope );
			//}
		}
	}

	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable--;
			cerr << "end of scope " << mReplaceVariable << endl;
		}
	} 

	return returnAttribute;
}
Пример #2
0
MySynthesizedAttribute
MyTraversal::evaluateRewriteSynthesizedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute,
		SubTreeSynthesizedAttributes synthesizedAttributeList )
{
	MySynthesizedAttribute returnAttribute;

	
	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				SgForStatement *forStat = isSgForStatement(astNode); 
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				for(size_t i=0; i<mAllFors.size(); i++) {
					if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) {
						ostringstream newFor;
						newFor << "for(";
						newFor << (*(forStat->get_init_stmt().begin()))->unparseToString();
						newFor << forStat->get_test_expr()->unparseToString() << ";" ;
						newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ;
						newFor << forStat->get_loop_body()->unparseToString();
						cout << " is blocked loop..." << endl;
						returnAttribute.replace( astNode, newFor.str() );
					}
				}
			} break;

		case V_SgVarRefExp: {
				cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() <<  endl;
				forBlockVector fors = inheritedAttribute.getForScopes();

				// replace variable occurrences in the loop kernel
				if(inheritedAttribute.getLoopKernel()) {
					for(size_t i=0;i<fors.size(); i++) {
						if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) &&
								( isSgVarRefExp(astNode)->get_type() == fors[i]->varType )
							) {
							string blockedVarName("blocked_");
							blockedVarName += fors[i]->varName;
							AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName );
							cout << "   replacing with '"<<blockedVarName<<"' " << endl;
						}
					}
				}
			} break;

		default:
			break;
	} // node type

	bool synth = false;
	for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin();
             i!= synthesizedAttributeList.end(); i++ ) {
                if( (*i).getVarRefFound() ) synth = true;
	}
	if( synth ) {
		returnAttribute.setVarRefFound( true );
		if(isSgStatement( astNode )) {
			cout << "   new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl;
			returnAttribute.setVarRefFound( false );
			//if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!?
			returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope );
			//}
		}
	}

	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable--;
			cerr << "end of scope " << mReplaceVariable << endl;
		}
	} 

	//if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work?
	if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) {
		// we're back at the loop kernel block, now replace and insert new loops...
		insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() );
	}

	return returnAttribute;
}
Пример #3
0
/**
 * Const-qualify immutable objects
 *
 * \todo count assignments, if only one, report violation
 */
bool DCL00_C(const SgNode *node ) {
  const SgInitializedName *varName = isSgInitializedName(node);
  if (!varName)
    return false;

  /**
   * Ignore variables generated by macros
   */
  if ((varName->get_name().getString().substr(0,2) == "__")
      ||  isCompilerGeneratedNode(node))
    return false;

  /**
   * Ignore global variables
   */
  if (isGlobalVar(varName))
    return false;

  /**
   * Ignore variables that are already const, are function pointers, or are
   * declared inside of a struct, enum, or as an argument to a function
   */
  SgType *varType = varName->get_type();
  if (isConstType(varType)
      || isConstType(varType->dereference())
      || isConstType(varType->dereference()->dereference())
      || isSgFunctionType(varType)
      || isSgClassType(varType)
      || findParentOfType(varName, SgCtorInitializerList)
      || findParentOfType(varName, SgEnumDeclaration)
      || findParentOfType(varName, SgClassDeclaration))
    return false;

  /**
   * DCL13-C is a subset of this rule, figure out which rule we are dealing
   * with here
   */
  std::string ruleStr;
  std::string errStr;
  if (findParentOfType(varName, SgFunctionParameterList)) {
    /** ignore function prototypes, just worry about the definitions */
    const SgFunctionDeclaration *fnDecl = findParentOfType(varName, SgFunctionDeclaration);
    /**
     * Disabling assertion due to C++ code
     */
    if (!fnDecl)
      return false;
    //		assert(fnDecl);
    if (!fnDecl->get_definition())
      return false;
    if (isSgPointerType(varName->get_type())
        ||  isSgArrayType(varName->get_type())) {
      ruleStr = "DCL13-C";
      errStr = "Declare function parameters that are pointers to values not changed by the function as const: ";
    } else {
      return false;
    }
  } else {
    ruleStr = "DCL00-C";
    errStr = "Const-qualify immutable objects: ";
  }

  /**
   * Ignore global variables or variables declared as extern
   */
  const SgScopeStatement *varScope = varName->get_scope();
  if (isSgGlobal(varScope) || isExternVar(varName))
    return false;

  FOREACH_SUBNODE(varScope, nodes, i, V_SgVarRefExp) {
    const SgVarRefExp *iVar = isSgVarRefExp(*i);
    assert(iVar);
    if (getRefDecl(iVar) != varName)
      continue;

    const SgNode *parent = iVar->get_parent();
    while (isSgCastExp(parent)) {
      parent = parent->get_parent();
    }
    assert(parent);

    /**
     * If the variable is written to or it's address is taken, we can no
     * longer be sure it should be const, if it's a struct and gets
     * dereferenced, who knows what's getting written there :/
     */
    if (varWrittenTo(iVar)
        ||  isSgArrowExp(parent)
        ||  findParentOfType(iVar, SgAddressOfOp))
      return false;

    /**
     * If the variable is a pointer or array, and we pass it to a function
     * or as an argument to pointer arithmetic, or assign it's value
     * somewhere, we can longer be sure it should be const
     */
    if ((isSgPointerType(varType) || isSgArrayType(varType))
        && (findParentOfType(iVar, SgFunctionCallExp)
            || isSgAddOp(parent)
            || isSgSubtractOp(parent)
            || isSgAssignOp(parent)
            || isSgPntrArrRefExp(parent)
            || isSgPointerDerefExp(parent)
            || isSgAssignInitializer(parent)))
      return false;
  }

  const std::string msg =  errStr + varName->get_name().getString();
  print_error(node, ruleStr.c_str(), msg.c_str(), true);
  return true;
}
Пример #4
0
// Functions required by the tree traversal mechanism
MyInheritedAttribute
MyTraversal::evaluateRewriteInheritedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute )
{
	MyInheritedAttribute returnAttribute = inheritedAttribute;

	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				SgForStatement *forStat = isSgForStatement(astNode); 

				forBlockInfo *inf = new forBlockInfo;
				inf->forStmt = forStat;
				SgInitializedName *varin = isSgInitializedName( forStat->get_traversalSuccessorContainer()[0] //for init
						->get_traversalSuccessorContainer()[0] // var decl
						->get_traversalSuccessorContainer()[0] // initialized name
						);
				assert( varin );
				inf->varName = varin->get_name().str();
				inf->varType = varin->get_type();
				inf->blocked = false;
				inf->blockSize = 0;

				returnAttribute.addForStatement( inf );
				mAllFors.push_back( inf );

				list<SgNode*> forList = NodeQuery::querySubTree( astNode, forStatementNodeQuery );
				if( (forList.size()==1) && // only the current loop?
						(returnAttribute.getForScopes().size()>1) ) {
					cerr << "   it is the innermost for loop " << endl;
					mpLoopBody = forStat->get_loop_body();
				}
			} break;

		default:
			break;
	}

	if(astNode == mpLoopBody) {
		bool loopsValid = true;
		
		// do some basic checks for validity
		forBlockVector fors = returnAttribute.getForScopes();
		for(size_t i=0;i<fors.size(); i++) {
			SgExpression *testExpr = fors[i]->forStmt->get_test_expr();
			SgExpression *incExpr  = fors[i]->forStmt->get_increment_expr();
			if(isSgPlusPlusOp(incExpr) ==NULL)  loopsValid = false;
			if(isSgLessThanOp(testExpr) ==NULL) loopsValid = false;
			else {
				if(! isSgVarRefExp(isSgLessThanOp(testExpr)->get_lhs_operand()) ) loopsValid = false;
			}
		}

		// this is the basic block of the innermost loop
		// only do trafos, if more than two nested loop nests, and we found the inner one
		if(loopsValid) {
			returnAttribute.setLoopKernel( true );
		} else {
			cout << " loop nest not valid, skipping transformation..." << endl;
		}
	}
	
	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable++;
			cerr << "nested scope found, #" << mReplaceVariable << endl;
		}
	} 

	return returnAttribute;
}
Пример #5
0
SgExpression * translateConstExpression(
  SgExpression * expr,
  const std::map<SgVariableSymbol *, SgVariableSymbol *> & param_to_local,
  const std::map<SgVariableSymbol *, SgVariableSymbol *> & iter_to_local
) {
  SgExpression * result = SageInterface::copyExpression(expr);

  std::map<SgVariableSymbol *, SgVariableSymbol *>::const_iterator it_sym_to_local;

  if (isSgVarRefExp(result)) {
    // Catch an issue when reading looptree from file. In this case, 'expr' may not have a valid parent.
    // If 'expr' is a SgVarRefExp, it causes an assertion to fail in SageInterface::replaceExpression

    SgVarRefExp * var_ref = (SgVarRefExp *)result;

    SgVariableSymbol * var_sym = var_ref->get_symbol();

    SgVariableSymbol * local_sym = NULL;

    it_sym_to_local = param_to_local.find(var_sym);
    if (it_sym_to_local != param_to_local.end())
      local_sym = it_sym_to_local->second;

    it_sym_to_local = iter_to_local.find(var_sym);
    if (it_sym_to_local != iter_to_local.end()) {
      assert(local_sym == NULL); // implies VarRef to a variable symbol which is both parameter and iterator... It does not make sense!

      local_sym = it_sym_to_local->second;
    }

    assert(local_sym != NULL); // implies VarRef to an unknown variable symbol (neither parameter or iterator)

    return SageBuilder::buildVarRefExp(local_sym);
  }
  
  std::vector<SgVarRefExp *> var_refs = SageInterface::querySubTree<SgVarRefExp>(result);
  std::vector<SgVarRefExp *>::const_iterator it_var_ref;
  for (it_var_ref = var_refs.begin(); it_var_ref != var_refs.end(); it_var_ref++) {
    SgVarRefExp * var_ref = *it_var_ref;
    SgVariableSymbol * var_sym = var_ref->get_symbol();

    SgVariableSymbol * local_sym = NULL;

    it_sym_to_local = param_to_local.find(var_sym);
    if (it_sym_to_local != param_to_local.end())
      local_sym = it_sym_to_local->second;

    it_sym_to_local = iter_to_local.find(var_sym);
    if (it_sym_to_local != iter_to_local.end()) {
      assert(local_sym == NULL); // implies VarRef to a variable symbol which is both parameter and iterator... It does not make sense!

      local_sym = it_sym_to_local->second;
    }

    assert(local_sym != NULL); // implies VarRef to an unknown variable symbol (neither parameter or iterator)

    SageInterface::replaceExpression(var_ref, SageBuilder::buildVarRefExp(local_sym), true);
  }

  return result;
}
Пример #6
0
std::string writeSgBinaryOpZ3(SgBinaryOp* op, SgExpression* lhs, SgExpression* rhs) {
	
	std::stringstream ss;
	std::string opStr;
	bool compAssign = false;
	if (isSgCompoundAssignOp(op)) {
		compAssign = true;
		opStr = getSgCompoundAssignOp(isSgCompoundAssignOp(op));
	
	}
	else {
		opStr = getSgBinaryOp(op);
	}
	ROSE_ASSERT(opStr != "unknown");
	std::string rhsstring;
	std::string lhsstring;
	lhsstring = getSgExpressionString(lhs);
	SgType* lhstyp;
	SgType* rhstyp;
	if (isSgArrayType(lhs->get_type())) {
	lhstyp = isSgArrayType(lhs->get_type())->get_base_type();	
	}
	else {
	lhstyp = lhs->get_type();
	}
	if (isSgArrayType(rhs->get_type())) {
	rhstyp = isSgArrayType(rhs->get_type())->get_base_type();
	}
	else {
	rhstyp = rhs->get_type();
	}
	if (isSgEnumType(lhs->get_type())) {
	}
	else {	
	ROSE_ASSERT(lhstyp == rhstyp);
	}	
	if (isSgValueExp(rhs)) {
		rhsstring = getSgValueExp(isSgValueExp(rhs));
	}
	else if (isSgUnaryOp(rhs)) {	
		rhsstring = getSgUnaryOp(isSgUnaryOp(rhs));
	}
		
	else {
		rhsstring = getSgExpressionString(rhs);
	}
	if (opStr == "/" && lhstyp->isIntegerType()) {
		opStr = "cdiv";
	} 
	if (opStr == "assign" || compAssign) {
		if (isSgVarRefExp(lhs)) {
		SgVarRefExp* lhsSgVarRefExp = isSgVarRefExp(lhs);
		int instances = SymbolToInstances[lhsSgVarRefExp->get_symbol()];
		std::stringstream instanceName;
		SymbolToInstances[lhsSgVarRefExp->get_symbol()] = instances + 1;
		std::string lhsname = SymbolToZ3[lhsSgVarRefExp->get_symbol()];
		instanceName << lhsname << "_" << (instances+1);
		SgType* varType = lhsSgVarRefExp->get_type();
		std::string typeZ3;
		if (varType->isFloatType()) {
			typeZ3 = "Real";
		}
		else if (varType->isIntegerType()) {
			typeZ3 = "Int";
		}
		else if (isSgEnumType(varType)) {
			typeZ3 = isSgEnumType(varType)->get_name().getString();
		}
		else {
			typeZ3 = "Unknown";
		}
		ss << "(declare-fun " << instanceName.str() << " () " << typeZ3 << ")\n";
		if (!compAssign) {  		
			ss << "(assert (= " << instanceName.str() << " " << rhsstring << "))";
		}
		else {
			std::stringstream oldInstanceName;
			oldInstanceName << lhsname << "_" << instances;
			ss << "(assert (= " << instanceName.str() << " (" << opStr << " " << oldInstanceName.str() << " " << rhsstring << ")))"; 
		}
		}
		
		else {
			ROSE_ASSERT(isSgPntrArrRefExp(lhs));
			std::string u_type;
			SgPntrArrRefExp* lhspntr = isSgPntrArrRefExp(lhs);
			SgVarRefExp* varlhspntr = isSgVarRefExp(lhspntr->get_lhs_operand());
			SgArrayType* arrTy = isSgArrayType(varlhspntr->get_type());
			if (arrTy->get_base_type()->isIntegerType()) {
				u_type = "Int";
			}
			else if (arrTy->get_base_type()->isFloatType()) {
				u_type = "Real";
			}
			else {
				std::cout << "unknown base type for array" << std::endl;
				ROSE_ASSERT(false);
			}
			std::stringstream oldInstanceName;
			SgVarRefExp* varexp = isSgVarRefExp((isSgPntrArrRefExp(lhs))->get_lhs_operand());
			oldInstanceName << SymbolToZ3[varexp->get_symbol()] << "_" << SymbolToInstances[varexp->get_symbol()];	
			int instances = SymbolToInstances[varexp->get_symbol()];
                	std::stringstream instanceName;
                	SymbolToInstances[varexp->get_symbol()] = instances + 1;
                	std::string lhsname = SymbolToZ3[varexp->get_symbol()];
                	instanceName << lhsname << "_" << instances+1;
			ss << "(declare-const " << instanceName.str() << " (Array Int " << u_type << "))\n ";	
			std::string indexstring = getSgExpressionString(isSgPntrArrRefExp(lhs)->get_rhs_operand());	
			ss << "(assert (= (store " << oldInstanceName.str() << " " << indexstring << " " << rhsstring << ") " << instanceName.str() << "))";
		}
	}	
	else if (opStr == "neq") {
	ss << "(not (= " << lhsstring << " " << rhsstring << "))";
	}
	else if (opStr == "or" || opStr == "and") {
		std::stringstream val_stream;	
		if (pathNodeTruthValue.find(op) != pathNodeTruthValue.end()) {
		bool logic_val = pathNodeTruthValue[op];
		//std::cout << ";and/or lhsstring " << lhsstring << "\n";
		//std::cout << ";and/or rhsstring " << rhsstring << "\n";
		if (opStr == "and") {
				
			if (logic_val) {
			
				std::string p_decl = "(assert (= " + lhsstring + " true))";
				declarations.push_back(p_decl);
				ss << rhsstring;
				//ss << "(and " << lhsstring << " " << rhsstring << ")";

			}
			else {
				std::string p_decl = "(assert (= " + lhsstring + " false))";
				declarations.push_back(p_decl);
				ss << "false";	
			}
		}
		else {
			if (logic_val) {
				std::string p_decl = "(assert (= " + lhsstring + " true))";
				declarations.push_back(p_decl);
				ss << "true"; 
			}
			else {
				std::string p_decl = "(assert (= " + lhsstring + " false))";
				declarations.push_back(p_decl);
				ss << rhsstring;
			}
		}
	}
	else {
		ss << "";
	}
	}
	else {	
	ss << "(" << opStr << " " << lhsstring << " " << rhsstring << ")";
	}
	return ss.str();
}
Пример #7
0
std::string getSgExpressionString(SgExpression* expNode) {
	//bool returnString = false;
	std::string expString;
	bool set_to_expression_val = false;
	VariantT var = expNode->variantT();
	if (isSgBinaryOp(expNode)) {
		SgBinaryOp* binOp = isSgBinaryOp(expNode);
		SgExpression* lhs_exp = binOp->get_lhs_operand();
		SgExpression* rhs_exp = binOp->get_rhs_operand();
		expString = writeSgBinaryOpZ3(binOp, lhs_exp, rhs_exp);
		if (isSgAssignOp(binOp) || isSgCompoundAssignOp(binOp)) {
			declarations.push_back(expString);
			expString = "";
		}
		else if (isSgEqualityOp(binOp) || isSgGreaterThanOp(binOp) || isSgGreaterOrEqualOp(binOp) || isSgLessThanOp(binOp) || isSgLessOrEqualOp(binOp) || isSgNotEqualOp(binOp) || isSgAndOp(binOp) || isSgOrOp(binOp)) {
		
		//set_to_expression_val = true;
		
		}
	}
	else if (isSgUnaryOp(expNode)) {
		expString = getSgUnaryOp(isSgUnaryOp(expNode));
	}
	else if (isSgValueExp(expNode)) {
		expString = getSgValueExp(isSgValueExp(expNode));
	}
	else {
	switch (var) {
		case V_SgCallExpression:
			std::cout << "SgCallExpression not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgClassNameRefExp:
			std::cout << "SgClassNameRefExp not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgConditionalExp:
			std::cout << "SgConditionalExp (trinary A ? B : C) not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;		
		case V_SgExprListExp:
			std::cout << "SgExprListExp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgFunctionRefExp:
			std::cout << "SgFunctionRefExp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgDeleteExp:
			std::cout << "SgDeleteExp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgInitializer:
			std::cout << "SgInitializer is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgNaryOp:
			std::cout << "SgNaryOp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgNewExp:
			std::cout << "SgNewExp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgNullExpression:
		
			expString = "; null expression";
			break;
		case V_SgRefExp:
			std::cout << "SgRefExp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgSizeOfOp:
			std::cout << "SgSizeOfOp is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgStatementExpression:
			std::cout << "SgStatementExpression is not yet implemented" << std::endl;
			expString = "";
			ROSE_ASSERT(false);
			break;
		case V_SgValueExp:
			std::cout << "V_SgValueExp should never be encountered" << std::endl;
			ROSE_ASSERT(false);
			expString = "";
			break;
			
		case V_SgVarRefExp:
			expString = getSgVarRefExp(isSgVarRefExp(expNode));
			break;
		default:
			std::cout << expNode->class_name() << " is not being considered for implementation";
			expString = "";
			#ifndef VERBOSE_COMPLETE
			ROSE_ASSERT(false);
			#endif
		}
		}
			
		/*if (set_to_expression_val) {
		std::stringstream exp_var;
		exp_var << "e_" << expression_count;
		expression_count++;
		
		std::string exp_var_decl = "(declare-const " + exp_var.str() + " Bool)";
		variables.push_back(exp_var_decl);
		std::string exp_var_val = "(assert (= " + exp_var.str() + " " + expString + "))";	
		expressions.push_back(exp_var_val);	
return exp_var.str();
		}
		else {
			return expString;
		}*/
		return expString;
	}
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);
   }