bool isMethodCall(SgFunctionCallExp *functionCall, bool &isDotExp)
{
  ROSE_ASSERT(functionCall != NULL);

  SgExpression *expression = functionCall->get_function();
  ROSE_ASSERT(expression != NULL);

  bool isMethod = false;
  isDotExp = false;

  switch(expression->variantT()) {
  case V_SgDotExp:
    {
      isMethod = true;

      SgDotExp *dotExp = isSgDotExp(expression);
      ROSE_ASSERT(dotExp != NULL);
	  
      SgExpression *lhs = dotExp->get_lhs_operand();
      ROSE_ASSERT(lhs != NULL);
	  
      SgPointerDerefExp *pointerDerefExp =
	isSgPointerDerefExp(lhs);
	  
      if ( pointerDerefExp != NULL ) {
	;
      } else {
	isDotExp = true;
      }

      break;
    }
  case V_SgMemberFunctionRefExp:
  case V_SgArrowExp:
    {
      isMethod = true;
      break;
    }
  case V_SgFunctionRefExp:
  case V_SgPointerDerefExp:
    {
      isMethod = false;
      break;
    }
  default:
    {
      std::cerr << "Was not expecting an " << expression->sage_class_name() << std::endl;
      std::cerr << "in a function call." << std::endl;
      ROSE_ABORT();
    }
  }

  return isMethod;
}
示例#2
0
void
UnparseFortran_type::unparseArrayType(SgType* type, SgUnparse_Info& info, bool printDim)
{
    // Examples:
    //   real, dimension(10, 10) :: A1, A2
    //   real, dimension(:) :: B1
    //   character(len=*) :: s1
#if 0
    curprint ("\n! Inside of UnparserFort::unparseArrayType \n");
#endif

    SgArrayType* array_type = isSgArrayType(type);
    ROSE_ASSERT(array_type != NULL);

    // I think that supressStrippedTypeName() and SkipBaseType() are redundant...
    if (info.supressStrippedTypeName() == false)
    {
        // DQ (1/16/2011): We only want to output the name of the stripped type once!
        SgType* stripType = array_type->stripType();
        unparseType(stripType, info);
        info.set_supressStrippedTypeName();
    }

    // DQ (8/5/2010): It is an error to treat an array of char as a string (see test2010_16.f90).
#if 0
    // dimension information
    SgExprListExp* dim = array_type->get_dim_info();

    // if (isCharType(array_type->get_base_type()))
    // if (false && isCharType(array_type->get_base_type()))
    if (isCharType(array_type->get_base_type()))
    {
        // a character type: must be treated specially
        ROSE_ASSERT(array_type->get_rank() == 1);
        curprint("(len=");

        SgExpressionPtrList::iterator it = dim->get_expressions().begin();
        if (it != dim->get_expressions().end())
        {
            SgExpression* expr = *it;
            if (expr->variantT() == V_SgSubscriptExpression)
            {
                // this is a subscript expression but all we want to unparse is the length
                // of the string, which should be the upper bound of the subscript expression
                SgSubscriptExpression* sub_expr = isSgSubscriptExpression(expr);
                ROSE_ASSERT(sub_expr != NULL);

                ROSE_ASSERT(unp != NULL);
                ROSE_ASSERT(unp->u_fortran_locatedNode != NULL);
                unp->u_fortran_locatedNode->unparseExpression(sub_expr->get_upperBound(), info);
            }
            else
            {
                // unparse the entire expression
                ROSE_ASSERT(unp != NULL);
                ROSE_ASSERT(unp->u_fortran_locatedNode != NULL);
                unp->u_fortran_locatedNode->unparseExpression(*it, info);
            }
        }
        else
        {
            curprint("*");
        }
        curprint(")");
    }
    else
    {
        // a non-character type

        // explicit-shape (explicit rank and bounds/extents)
        // assumed-shape (explicit rank; unspecified bounds/extents)
        // deferred-shape (explicit rank; unspecified bounds/extents)
        // assumed-size (explicit ranks, explicit bounds/extents except last dim)
        ROSE_ASSERT(array_type->get_rank() >= 1);
        curprint(", DIMENSION");

        ROSE_ASSERT(unp != NULL);
        ROSE_ASSERT(unp->u_fortran_locatedNode != NULL);
        // unp->u_fortran_locatedNode->unparseExprList(dim, info); // adds parens
        // unp->u_fortran_locatedNode->UnparseLanguageIndependentConstructs::unparseExprList(dim, info); // adds parens

        // curprint("(");
        // curprint( StringUtility::numberToString(array_type->get_rank()) );
        // curprint(")");

        // unp->u_fortran_locatedNode->unparseExpression(array_type->get_dim_info(),info);
        unp->u_fortran_locatedNode->unparseExprList(array_type->get_dim_info(),info,/* output parens */ true);
    }
#else

    if (printDim)
    {
        ROSE_ASSERT(array_type->get_rank() >= 1);
        curprint(array_type->get_isCoArray()? ", CODIMENSION": ", DIMENSION");

        ROSE_ASSERT(unp != NULL);
        ROSE_ASSERT(unp->u_fortran_locatedNode != NULL);

        if (array_type->get_isCoArray())
        {   // print codimension info
            curprint("[");
            unp->u_fortran_locatedNode->unparseExprList(array_type->get_dim_info(),info,/* do not output parens */ false);
            curprint("]");
        }
        else  // print dimension info
            unp->u_fortran_locatedNode->unparseExprList(array_type->get_dim_info(),info,/* output parens */ true);
    }

    // DQ (1/16/2011): Plus unparse the base type...(unless it will just output the stripped types name).
    if (array_type->get_base_type()->containsInternalTypes() == true)
    {
        unparseType(array_type->get_base_type(), info, printDim);
    }
#endif

#if 0
    curprint ("\n! Leaving UnparserFort::unparseArrayType \n");
#endif
}
示例#3
0
void
MarkLhsValues::visit(SgNode* node)
   {
  // DQ (1/19/2008): Fixup the get_lvalue() member function which is common on expressions.
  // printf ("In TestLValueExpressions::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
#if 0
     Sg_File_Info* fileInfo = node->get_file_info();

     printf ("In MarkLhsValues::visit(): node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo);
     if (fileInfo != NULL)
        {
          bool isCompilerGenerated = fileInfo->isCompilerGenerated();
          std::string filename = fileInfo->get_filenameString();
          int line_number = fileInfo->get_line();
          int column_number = fileInfo->get_line();

          printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str());
        }
#endif

  // This function most often sets the SgVarRefExp which appears as an lhs operand in a limited set of binary operators.

     SgExpression* expression = isSgExpression(node);
     if (expression != NULL)
        {
#if 0
          printf ("MarkLhsValues::visit(): calling expression->get_lvalue() on expression = %p = %s \n",expression,expression->class_name().c_str());
#endif
          SgBinaryOp* binaryOperator = isSgBinaryOp(expression);

          if (binaryOperator != NULL)
             {
               switch (expression->variantT())
                  {
                 // IR nodes that have an l-value (required by C/C++/Fortran standard)
                    case V_SgAssignOp:
                    case V_SgAndAssignOp:
                    case V_SgDivAssignOp:
                    case V_SgIorAssignOp:
                    case V_SgLshiftAssignOp:
                    case V_SgMinusAssignOp:
                    case V_SgModAssignOp:
                    case V_SgMultAssignOp:
                    case V_SgPlusAssignOp:
                    case V_SgRshiftAssignOp:
                    case V_SgXorAssignOp:
                       {
                         SgExpression* lhs = binaryOperator->get_lhs_operand();
                         ROSE_ASSERT(lhs != NULL);
                         SgExpression* rhs = binaryOperator->get_rhs_operand();
                         ROSE_ASSERT(rhs != NULL);

                      // This is violated by the ROSE/tests/nonsmoke/functional/roseTests/astInliningTests/pass16.C test code!
                      // ROSE_ASSERT(lhs->get_lvalue() == true);

                      // This is a value that I know has to be set, the AST generation in EDG/Sage and OFP/Sage
                      // sets this properly, but some transformations of the AST do not, so we fix it up here.
                         lhs->set_lvalue(true);
                         rhs->set_lvalue(false);
                         break;
                       }

                 // These cases are less clear so don't explicitly mark it as an l-value!
                    case V_SgDotExp:
                    case V_SgArrowExp:
                       {
                         SgExpression* lhs = binaryOperator->get_lhs_operand();
                         ROSE_ASSERT(lhs != NULL);
#if WARN_ABOUT_ATYPICAL_LVALUES
                         printf ("L-value test for SgBinaryOp = %s: not clear how to assert value -- lhs->get_lvalue() = %s \n",binaryOperator->class_name().c_str(),lhs->get_lvalue() ? "true" : "false");
#endif
                      // ROSE_ASSERT(lhs->get_lvalue() == true);
                         break;
                       }

                 // DQ (10/9/2008): For the Fortran user defined operator, the lhs is not an L-value.
                 // This represents my understanding, because assignment is explicitly handled separately.
                    case V_SgUserDefinedBinaryOp:
                       {
                         SgExpression* lhs = binaryOperator->get_lhs_operand();
                         ROSE_ASSERT(lhs != NULL);
                         SgExpression* rhs = binaryOperator->get_rhs_operand();
                         ROSE_ASSERT(rhs != NULL);

                      // This is a value that I know has to be set, the AST generation in EDG/Sage and OFP/Sage
                      // sets this properly, but some transformations of the AST do not, so we fix it up here.
                         lhs->set_lvalue(false);
                         rhs->set_lvalue(false);
                         break;
                       }

                    default:
                       {
                      // Make sure that the lhs is not an L-value
                         SgExpression* lhs = binaryOperator->get_lhs_operand();
                         ROSE_ASSERT(lhs != NULL);

#if WARN_ABOUT_ATYPICAL_LVALUES
                         if (lhs->get_lvalue() == true)
                            {
                              printf ("Error for lhs = %p = %s = %s in binary expression = %s \n",
                                   lhs,lhs->class_name().c_str(),SageInterface::get_name(lhs).c_str(),expression->class_name().c_str());
                              binaryOperator->get_startOfConstruct()->display("Error for lhs: lhs->get_lvalue() == true: debug");
                            }
#endif

                      // ROSE_ASSERT(lhs->get_lvalue() == false);
                       }
                  }

               //SgExpression* rhs = binaryOperator->get_rhs_operand();
               // Liao 3/14/2011. This function is called by builders for binary expressions. 
               // These builders can accept empty right hand operands.
               // ROSE_ASSERT(rhs != NULL);

#if WARN_ABOUT_ATYPICAL_LVALUES
               if (rhs != NULL)
                 if (rhs->get_lvalue() == true)
                  {
                    printf ("Error for rhs = %p = %s = %s in binary expression = %s \n",
                         rhs,rhs->class_name().c_str(),SageInterface::get_name(rhs).c_str(),expression->class_name().c_str());
                    binaryOperator->get_startOfConstruct()->display("Error for rhs: rhs->get_lvalue() == true: debug");
                  }
#endif

            // ROSE_ASSERT(rhs->get_lvalue() == false);
             }
          
          SgUnaryOp* unaryOperator = isSgUnaryOp(expression);
          if (unaryOperator != NULL)
             {
               switch (expression->variantT())
                  {
                 // IR nodes that should have a valid lvalue
                 // What about SgAddressOfOp?
              
                    case V_SgAddressOfOp: break; // JJW 1/31/2008

                    case V_SgMinusMinusOp:
                    case V_SgPlusPlusOp:
                       {
                         SgExpression* operand = unaryOperator->get_operand();
                         ROSE_ASSERT(operand != NULL);

#if WARN_ABOUT_ATYPICAL_LVALUES
                      // if (operand->get_lvalue() == true)
                         if (operand->get_lvalue() == false)
                            {
                              printf ("Error for operand = %p = %s = %s in unary expression (SgMinusMinusOp or SgPlusPlusOp) = %s \n",
                                   operand,operand->class_name().c_str(),SageInterface::get_name(operand).c_str(),expression->class_name().c_str());
                              unaryOperator->get_startOfConstruct()->display("Error for operand: operand->get_lvalue() == true: debug");
                            }
#endif

                      // ROSE_ASSERT(operand->get_lvalue() == false);
                         operand->set_lvalue(true);
                      // ROSE_ASSERT(operand->get_lvalue() == true);
                         break;
                       }

                    case V_SgThrowOp:
                       {
#if WARN_ABOUT_ATYPICAL_LVALUES
                      // Note that the gnu " __throw_exception_again;" can cause a SgThrowOp to now have an operand!
                         SgExpression* operand = unaryOperator->get_operand();
                         if (operand == NULL)
                            {
                              printf ("Warning: operand == NULL in SgUnaryOp = %s (likely caused by __throw_exception_again) \n",expression->class_name().c_str());
                           // unaryOperator->get_startOfConstruct()->display("Error: operand == NULL in SgUnaryOp: debug");
                            }
#endif
                      // ROSE_ASSERT(operand != NULL);
                         break;
                       }

                 // DQ (10/9/2008): For the Fortran user defined operator, the operand is not an L-value.
                 // This represents my understanding, because assignment is explicitly handled separately.
                    case V_SgUserDefinedUnaryOp:
                       {
                         SgExpression* operand = unaryOperator->get_operand();
                         ROSE_ASSERT(operand != NULL);

                         operand->set_lvalue(false);
                       }

                 // Added to address problem on Qing's machine using g++ 4.0.2
                    case V_SgNotOp:

                 // These are where some error occur.  I want to isolate then so that I know the current status of where lvalues are not marked correctly!
                    case V_SgPointerDerefExp:
                    case V_SgCastExp:
                    case V_SgMinusOp:
                    case V_SgBitComplementOp:
                 // case V_SgPlusOp:
                       {
                         SgExpression* operand = unaryOperator->get_operand();
                         ROSE_ASSERT(operand != NULL);

#if WARN_ABOUT_ATYPICAL_LVALUES
                      // Most of the time this is false, we only want to know when it is true
                         if (operand->get_lvalue() == true)
                            {
                              printf ("L-value test for SgUnaryOp = %s: not clear how to assert value -- operand->get_lvalue() = %s \n",unaryOperator->class_name().c_str(),operand->get_lvalue() ? "true" : "false");
                           // unaryOperator->get_startOfConstruct()->display("L-value test for SgUnaryOp: operand->get_lvalue() == true: debug");
                            }
#endif
                      // ROSE_ASSERT(operand->get_lvalue() == false);
                         break;
                       }

                    default:
                       {
                         SgExpression* operand = unaryOperator->get_operand();
                         ROSE_ASSERT(operand != NULL);

#if WARN_ABOUT_ATYPICAL_LVALUES
                         if (operand->get_lvalue() == true)
                            {
                              printf ("Error for operand = %p = %s = %s in unary expression = %s \n",
                                   operand,operand->class_name().c_str(),SageInterface::get_name(operand).c_str(),expression->class_name().c_str());
                              unaryOperator->get_startOfConstruct()->display("Error for operand: operand->get_lvalue() == true: debug");
                            }
#endif

                      // DQ (10/9/2008): What is the date and author for this comment?  Is it fixed now? Was it made into a test code?
                      // Note that this fails for line 206 of file: include/g++_HEADERS/hdrs1/ext/mt_allocator.h
                         ROSE_ASSERT(operand->get_lvalue() == false);
                       }          
                  }
             }
        }
   }
// Do finite differencing on one expression within one context.  The expression
// must be defined and valid within the entire body of root.  The rewrite rules
// are used to simplify expressions.  When a variable var is updated from
// old_value to new_value, an expression of the form (var, (old_value,
// new_value)) is created and rewritten.  The rewrite rules may either produce
// an arbitrary expression (which will be used as-is) or one of the form (var,
// (something, value)) (which will be changed to (var = value)).
void doFiniteDifferencingOne(SgExpression* e, 
                             SgBasicBlock* root,
                             RewriteRule* rules)
   {
     SgStatementPtrList& root_stmts = root->get_statements();
     SgStatementPtrList::iterator i;
     for (i = root_stmts.begin(); i != root_stmts.end(); ++i)
        {
          if (expressionComputedIn(e, *i))
               break;
        }
     if (i == root_stmts.end())
          return; // Expression is not used within root, so quit
     vector<SgVariableSymbol*> used_symbols = SageInterface::getSymbolsUsedInExpression(e);
     SgName cachename = "cache_fd__"; cachename << ++SageInterface::gensym_counter;
     SgVariableDeclaration* cachedecl = new SgVariableDeclaration(SgNULL_FILE, cachename, e->get_type(),0 /* new SgAssignInitializer(SgNULL_FILE, e) */);
     SgInitializedName* cachevar = cachedecl->get_variables().back();
     ROSE_ASSERT (cachevar);
     root->get_statements().insert(i, cachedecl);
     cachedecl->set_parent(root);
     cachedecl->set_definingDeclaration(cachedecl);
     cachevar->set_scope(root);
     SgVariableSymbol* sym = new SgVariableSymbol(cachevar);
     root->insert_symbol(cachename, sym);
     SgVarRefExp* vr = new SgVarRefExp(SgNULL_FILE, sym);
     vr->set_endOfConstruct(SgNULL_FILE);
     replaceCopiesOfExpression(e, vr, root);

     vector<SgExpression*> modifications_to_used_symbols;
     FdFindModifyingStatementsVisitor(used_symbols, modifications_to_used_symbols).go(root);

     cachedecl->addToAttachedPreprocessingInfo( 
          new PreprocessingInfo(PreprocessingInfo::CplusplusStyleComment,(string("// Finite differencing: ") + 
               cachename.str() + " is a cache of " + 
               e->unparseToString()).c_str(),"Compiler-Generated in Finite Differencing",0, 0, 0, PreprocessingInfo::before));

     if (modifications_to_used_symbols.size() == 0)
        {
          SgInitializer* cacheinit = new SgAssignInitializer(SgNULL_FILE, e);
          e->set_parent(cacheinit);
          cachevar->set_initializer(cacheinit);
          cacheinit->set_parent(cachevar);
        }
       else
        {
          for (unsigned int i = 0; i < modifications_to_used_symbols.size(); ++i)
             {
               SgExpression* modstmt = modifications_to_used_symbols[i];
#ifdef FD_DEBUG
               cout << "Updating cache after " << modstmt->unparseToString() << endl;
#endif
               SgExpression* updateCache = 0;
               SgVarRefExp* varref = new SgVarRefExp(SgNULL_FILE, sym);
               varref->set_endOfConstruct(SgNULL_FILE);
               SgTreeCopy tc;
               SgExpression* eCopy = isSgExpression(e->copy(tc));
               switch (modstmt->variantT())
                  {
                    case V_SgAssignOp:
                       {
                         SgAssignOp* assignment = isSgAssignOp(modstmt);
                         assert (assignment);
                         SgExpression* lhs = assignment->get_lhs_operand();
                         SgExpression* rhs = assignment->get_rhs_operand();
                         replaceCopiesOfExpression(lhs, rhs, eCopy);
                       }
                    break;

                    case V_SgPlusAssignOp:
                    case V_SgMinusAssignOp:
                    case V_SgAndAssignOp:
                    case V_SgIorAssignOp:
                    case V_SgMultAssignOp:
                    case V_SgDivAssignOp:
                    case V_SgModAssignOp:
                    case V_SgXorAssignOp:
                    case V_SgLshiftAssignOp:
                    case V_SgRshiftAssignOp:
                       {
                         SgBinaryOp* assignment = isSgBinaryOp(modstmt);
                         assert (assignment);
                         SgExpression* lhs = assignment->get_lhs_operand();
                         SgExpression* rhs = assignment->get_rhs_operand();
                         SgTreeCopy tc;
                         SgExpression* rhsCopy = isSgExpression(rhs->copy(tc));
                         SgExpression* newval = 0;
                         switch (modstmt->variantT())
                            {
#define DO_OP(op, nonassignment) \
                              case V_##op: { \
                                   newval = new nonassignment(SgNULL_FILE, lhs, rhsCopy); \
                                   newval->set_endOfConstruct(SgNULL_FILE); \
                              } \
                              break

                              DO_OP(SgPlusAssignOp, SgAddOp);
                              DO_OP(SgMinusAssignOp, SgSubtractOp);
                              DO_OP(SgAndAssignOp, SgBitAndOp);
                              DO_OP(SgIorAssignOp, SgBitOrOp);
                              DO_OP(SgMultAssignOp, SgMultiplyOp);
                              DO_OP(SgDivAssignOp, SgDivideOp);
                              DO_OP(SgModAssignOp, SgModOp);
                              DO_OP(SgXorAssignOp, SgBitXorOp);
                              DO_OP(SgLshiftAssignOp, SgLshiftOp);
                              DO_OP(SgRshiftAssignOp, SgRshiftOp);
#undef DO_OP

                              default: break;
                            }
                         assert (newval);
                         replaceCopiesOfExpression(lhs, newval, eCopy);
                       }
                    break;

                    case V_SgPlusPlusOp:
                       {
                         SgExpression* lhs = isSgPlusPlusOp(modstmt)->get_operand();
                         SgIntVal* one = new SgIntVal(SgNULL_FILE, 1);
                         one->set_endOfConstruct(SgNULL_FILE);
                         SgAddOp* add = new SgAddOp(SgNULL_FILE, lhs, one);
                         add->set_endOfConstruct(SgNULL_FILE);
                         lhs->set_parent(add);
                         one->set_parent(add);
                         replaceCopiesOfExpression(lhs,add,eCopy);
                            }
                    break;

                    case V_SgMinusMinusOp:
                       {
                         SgExpression* lhs = isSgMinusMinusOp(modstmt)->get_operand();
                         SgIntVal* one = new SgIntVal(SgNULL_FILE, 1);
                         one->set_endOfConstruct(SgNULL_FILE);
                         SgSubtractOp* sub = new SgSubtractOp(SgNULL_FILE, lhs, one);
                         sub->set_endOfConstruct(SgNULL_FILE);
                         lhs->set_parent(sub);
                         one->set_parent(sub);
                         replaceCopiesOfExpression(lhs,sub,eCopy);
                       }
                    break;

                    default:
                         cerr << modstmt->sage_class_name() << endl;
                         assert (false);
                         break;
                  }

#ifdef FD_DEBUG
            cout << "e is " << e->unparseToString() << endl;
            cout << "eCopy is " << eCopy->unparseToString() << endl;
#endif
               updateCache = doFdVariableUpdate(rules, varref, e, eCopy);
#ifdef FD_DEBUG
            cout << "updateCache is " << updateCache->unparseToString() << endl;
#endif
               if (updateCache)
                  {
                    ROSE_ASSERT(modstmt != NULL);
                    SgNode* ifp = modstmt->get_parent();
                    SgCommaOpExp* comma = new SgCommaOpExp(SgNULL_FILE, updateCache, modstmt);
                    modstmt->set_parent(comma);
                    updateCache->set_parent(comma);

                    if (ifp == NULL)
                       {
                         printf ("modstmt->get_parent() == NULL modstmt = %p = %s \n",modstmt,modstmt->class_name().c_str());
                         modstmt->get_startOfConstruct()->display("modstmt->get_parent() == NULL: debug");
                       }
                    ROSE_ASSERT(ifp != NULL);
#ifdef FD_DEBUG
                 cout << "New expression is " << comma->unparseToString() << endl;
                 cout << "IFP is " << ifp->sage_class_name() << ": " << ifp->unparseToString() << endl;
#endif
                    if (isSgExpression(ifp))
                       {
                         isSgExpression(ifp)->replace_expression(modstmt, comma);
                         comma->set_parent(ifp);
                       }
                      else
                       {
                      // DQ (12/16/2006): Need to handle cases that are not SgExpression (now that SgExpressionRoot is not used!)
                      // cerr << ifp->sage_class_name() << endl;
                      // assert (!"Bad parent type for inserting comma expression");
                         SgStatement* statement = isSgStatement(ifp);
                         if (statement != NULL)
                            {
#ifdef FD_DEBUG
                              printf ("Before statement->replace_expression(): statement = %p = %s modstmt = %p = %s \n",statement,statement->class_name().c_str(),modstmt,modstmt->class_name().c_str());
                              SgExprStatement* expresionStatement = isSgExprStatement(statement);
                              if (expresionStatement != NULL)
                                 {
                                   SgExpression* expression = expresionStatement->get_expression();
                                   printf ("expressionStatement expression = %p = %s \n",expression,expression->class_name().c_str());
                                 }
#endif
                              statement->replace_expression(modstmt, comma);
                              comma->set_parent(statement);
                            }
                           else
                            {
                              ROSE_ASSERT(ifp != NULL);
                              printf ("Error: parent is neither a SgExpression nor a SgStatement ifp = %p = %s \n",ifp,ifp->class_name().c_str());
                              ROSE_ASSERT(false);
                            }
                       }

#ifdef FD_DEBUG
                    cout << "IFP is now " << ifp->unparseToString() << endl;
#endif
                  }
             }
        }
   }
SgFunctionDeclaration * 
getFunctionDeclaration(SgFunctionCallExp *functionCall) 
{ 
  SgFunctionDeclaration *funcDec = NULL; 

  SgExpression *expression = functionCall->get_function();
  ROSE_ASSERT(expression != NULL);

  switch(expression->variantT()) {
  case V_SgMemberFunctionRefExp:
    {
      SgMemberFunctionRefExp *memberFunctionRefExp =
	isSgMemberFunctionRefExp(expression);
      ROSE_ASSERT(memberFunctionRefExp != NULL);

      funcDec = memberFunctionRefExp->get_symbol_i()->get_declaration(); 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgDotExp:
    {
      SgDotExp *dotExp = isSgDotExp(expression);
      ROSE_ASSERT(dotExp != NULL);

      if(dotExp->get_traversalSuccessorContainer().size()>=2) { 

	SgMemberFunctionRefExp *memberFunctionRefExp = 
	  isSgMemberFunctionRefExp(dotExp->get_traversalSuccessorContainer()[1]); 
	funcDec = memberFunctionRefExp->get_symbol_i()->get_declaration(); 
      } 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgArrowExp:
    {
      SgArrowExp *arrowExp = isSgArrowExp(expression);
      ROSE_ASSERT(arrowExp != NULL);

      if(arrowExp->get_traversalSuccessorContainer().size()>=2) { 

	SgMemberFunctionRefExp *memberFunctionRefExp = 
	  isSgMemberFunctionRefExp(arrowExp->get_traversalSuccessorContainer()[1]); 
	funcDec = memberFunctionRefExp->get_symbol_i()->get_declaration(); 
      } 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgFunctionRefExp:
    {
      SgFunctionRefExp *functionRefExp = 
	isSgFunctionRefExp(expression);
      ROSE_ASSERT(functionRefExp != NULL);

      // found a standard function reference  
      funcDec = functionRefExp->get_symbol_i()->get_declaration(); 

      ROSE_ASSERT(funcDec != NULL);

      break;
    }
  case V_SgPointerDerefExp:
    {
      ROSE_ABORT();
      break;
    }
  default:
    {
      ROSE_ABORT();
    }
  }

  return funcDec; 
} 
示例#6
0
set<SgInitializedName*> computeLiveVars(SgStatement* stmt, const X86CTranslationPolicy& conv, map<SgLabelStatement*, set<SgInitializedName*> >& liveVarsForLabels, set<SgInitializedName*> currentLiveVars, bool actuallyRemove) {
  switch (stmt->variantT()) {
    case V_SgBasicBlock: {
      const SgStatementPtrList& stmts = isSgBasicBlock(stmt)->get_statements();
      for (size_t i = stmts.size(); i > 0; --i) {
        currentLiveVars = computeLiveVars(stmts[i - 1], conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      }
      return currentLiveVars;
    }
    case V_SgPragmaDeclaration: return currentLiveVars;
    case V_SgDefaultOptionStmt: return currentLiveVars;
    case V_SgCaseOptionStmt: {
      return computeLiveVars(isSgCaseOptionStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
    }
    case V_SgLabelStatement: {
      liveVarsForLabels[isSgLabelStatement(stmt)] = currentLiveVars;
      return currentLiveVars;
    }
    case V_SgGotoStatement: {
      return liveVarsForLabels[isSgGotoStatement(stmt)->get_label()];
    }
    case V_SgSwitchStatement: {
      SgSwitchStatement* s = isSgSwitchStatement(stmt);
      SgBasicBlock* swBody = isSgBasicBlock(s->get_body());
      ROSE_ASSERT (swBody);
      const SgStatementPtrList& bodyStmts = swBody->get_statements();
      set<SgInitializedName*> liveForBody; // Assumes any statement in the body is possible
      for (size_t i = 0; i < bodyStmts.size(); ++i) {
        setUnionInplace(liveForBody, computeLiveVars(bodyStmts[i], conv, liveVarsForLabels, currentLiveVars, actuallyRemove));
      }
      return computeLiveVars(s->get_item_selector(), conv, liveVarsForLabels, liveForBody, actuallyRemove);
    }
    case V_SgContinueStmt: {
      return makeAllPossibleVars(conv);
    }
    case V_SgIfStmt: {
      set<SgInitializedName*> liveForBranches = computeLiveVars(isSgIfStmt(stmt)->get_true_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove);
      setUnionInplace(liveForBranches, (isSgIfStmt(stmt)->get_false_body() != NULL ? computeLiveVars(isSgIfStmt(stmt)->get_false_body(), conv, liveVarsForLabels, currentLiveVars, actuallyRemove) : set<SgInitializedName*>()));
      return computeLiveVars(isSgIfStmt(stmt)->get_conditional(), conv, liveVarsForLabels, liveForBranches, actuallyRemove);
    }
    case V_SgWhileStmt: {
      while (true) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, false);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, false);
        setUnionInplace(currentLiveVars, liveVarsSave);
        if (liveVarsSave == currentLiveVars) break;
      }
      if (actuallyRemove) {
        set<SgInitializedName*> liveVarsSave = currentLiveVars;
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_body(), conv, liveVarsForLabels, currentLiveVars, true);
        currentLiveVars = computeLiveVars(isSgWhileStmt(stmt)->get_condition(), conv, liveVarsForLabels, currentLiveVars, true);
        setUnionInplace(currentLiveVars, liveVarsSave);
      }
      return currentLiveVars;
    }
    case V_SgBreakStmt: return set<SgInitializedName*>();
    case V_SgExprStatement: {
      SgExpression* e = isSgExprStatement(stmt)->get_expression();
      switch (e->variantT()) {
        case V_SgAssignOp: {
          SgVarRefExp* lhs = isSgVarRefExp(isSgAssignOp(e)->get_lhs_operand());
          ROSE_ASSERT (lhs);
          SgInitializedName* in = lhs->get_symbol()->get_declaration();
          if (currentLiveVars.find(in) == currentLiveVars.end()) {
            if (actuallyRemove) {
              // cerr << "Removing assignment " << e->unparseToString() << endl;
              isSgStatement(stmt->get_parent())->remove_statement(stmt);
            }
            return currentLiveVars;
          } else {
            currentLiveVars.erase(in);
            getUsedVariables(isSgAssignOp(e)->get_rhs_operand(), currentLiveVars);
            return currentLiveVars;
          }
        }
        case V_SgFunctionCallExp: {
          getUsedVariables(e, currentLiveVars);
          SgFunctionRefExp* fr = isSgFunctionRefExp(isSgFunctionCallExp(e)->get_function());
          ROSE_ASSERT (fr);
          if (fr->get_symbol()->get_declaration() == conv.interruptSym->get_declaration()) {
            setUnionInplace(currentLiveVars, makeAllPossibleVars(conv));
            return currentLiveVars;
          } else {
            return currentLiveVars;
          }
        }
        default: {
          getUsedVariables(e, currentLiveVars);
          return currentLiveVars;
        }
      }
    }
    case V_SgVariableDeclaration: {
      ROSE_ASSERT (isSgVariableDeclaration(stmt)->get_variables().size() == 1);
      SgInitializedName* in = isSgVariableDeclaration(stmt)->get_variables()[0];
      bool isConst = isConstType(in->get_type());
      if (currentLiveVars.find(in) == currentLiveVars.end() && isConst) {
        if (actuallyRemove) {
          // cerr << "Removing decl " << stmt->unparseToString() << endl;
          isSgStatement(stmt->get_parent())->remove_statement(stmt);
        }
        return currentLiveVars;
      } else {
        currentLiveVars.erase(in);
        if (in->get_initializer()) {
          getUsedVariables(in->get_initializer(), currentLiveVars);
        }
        return currentLiveVars;
      }
    }
    default: cerr << "computeLiveVars: " << stmt->class_name() << endl; abort();
  }
}
示例#7
0
void
fixupReferencesToGlobalVariables ( Rose_STL_Container<SgVarRefExp*> & variableReferenceList, SgVariableSymbol* globalClassVariableSymbol)
   {
  // Now fixup the SgVarRefExp to reference the global variables through a struct
     for (Rose_STL_Container<SgVarRefExp*>::iterator var = variableReferenceList.begin(); var != variableReferenceList.end(); var++)
        {
          assert(*var != NULL);
       // printf ("Variable reference for %s \n",(*var)->get_symbol()->get_declaration()->get_name().str());

          SgNode* parent = (*var)->get_parent();
          assert(parent != NULL);

       // If this is not an expression then is likely a meaningless statement such as ("x;")
          SgExpression* parentExpression = isSgExpression(parent);
          assert(parentExpression != NULL);

       // Build the reference through the global class variable ("x" --> "AMPI_globals.x")

       // Build source position informaiton (marked as transformation)
          Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
          assert(fileInfo != NULL);

       // Build "AMPI_globals"
          SgExpression* lhs = new SgVarRefExp(fileInfo,globalClassVariableSymbol);
          assert(lhs != NULL);
       // Build "AMPI_globals.x" from "x"
          SgDotExp* globalVariableReference = new SgDotExp(fileInfo,lhs,*var);
          assert(globalVariableReference != NULL);

          if (parentExpression != NULL)
             {
            // Introduce reference to *var through the data structure

            // case of binary operator
               SgUnaryOp* unaryOperator = isSgUnaryOp(parentExpression);
               if (unaryOperator != NULL)
                  {
                    unaryOperator->set_operand(globalVariableReference);
                  }
                 else
                  {
                 // case of binary operator
                    SgBinaryOp* binaryOperator = isSgBinaryOp(parentExpression);
                    if (binaryOperator != NULL)
                       {
                      // figure out if the *var is on the lhs or the rhs
                         if (binaryOperator->get_lhs_operand() == *var)
                            {
                              binaryOperator->set_lhs_operand(globalVariableReference);
                            }
                           else
                            {
                              assert(binaryOperator->get_rhs_operand() == *var);
                              binaryOperator->set_rhs_operand(globalVariableReference);
                            }
                       }
                      else
                       {
                      // ignore these cases for now!
                         switch(parentExpression->variantT())
                            {
                           // Where the variable appers in the function argument list the parent is a SgExprListExp
                              case V_SgExprListExp:
                                 {
                                   printf ("Sorry not implemented, case of global variable in function argument list ... \n");
                                   assert(false);
                                   break;
                                 }
                              case V_SgInitializer:
                              case V_SgRefExp:
                              case V_SgVarArgOp:
                              default:
                                 {
                                   printf ("Error: default reached in switch  parentExpression = %p = %s \n",parentExpression,parentExpression->class_name().c_str());
                                   assert(false);
                                 }
                            }
                       }
                  }
             }
        }
   }
示例#8
0
void SimpleInstrumentation::visit ( SgNode* astNode )
   {
     switch(astNode->variantT()) 
        {
          case V_SgFunctionCallExp:
             {
               SgFunctionCallExp *functionCallExp = isSgFunctionCallExp(astNode);
               SgExpression *function = functionCallExp->get_function();
               ROSE_ASSERT(function);
               switch (function->variantT())
                  {
                    case V_SgFunctionRefExp:
                       {
                         SgFunctionRefExp *functionRefExp = isSgFunctionRefExp(function);
                         SgFunctionSymbol *symbol = functionRefExp->get_symbol();
                         ROSE_ASSERT(symbol != NULL);
                         SgFunctionDeclaration *functionDeclaration = symbol->get_declaration();
                         ROSE_ASSERT(functionDeclaration != NULL);
                         if (symbol == functionSymbol)
                            {
                           // Now we know that we have found the correct function call 
                           // (even in the presence of overloading or other forms of hidding)
                           // Now fixup the symbol and type of the SgFunctionRefExp object to 
                           // reflect the new function to be called (after this we still have to 
                           // fixup the argument list in the SgFunctionCallExp.

                           // We only want to build the decalration once (and insert it into the global scope)
                           // after that we save the symbol and reuse it.
                              if (newFunctionSymbol == NULL)
                                 {
                                   SgFunctionType* originalFunctionType = isSgFunctionType(functionSymbol->get_type());
                                   ROSE_ASSERT(originalFunctionType != NULL);
                                   newFunctionSymbol = buildNewFunctionDeclaration (TransformationSupport::getStatement(astNode),originalFunctionType);
                                 }

                              ROSE_ASSERT(newFunctionSymbol != NULL);
                              ROSE_ASSERT(newFunctionSymbol->get_type() != NULL);

                              functionRefExp->set_symbol(newFunctionSymbol);
                            }

                         break;
                       }
                    default:
                         cerr<<"warning: unrecognized variant: "<<function->class_name();
                  }
               break;
             }

          case V_SgFunctionDeclaration:
             {
               SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(astNode);
               string functionName = functionDeclaration->get_name().str();
               if (functionName == "send")
                  {
                    SgFunctionType *functionType = functionDeclaration->get_type();
                    ROSE_ASSERT(functionType != NULL);
                    bool foundFunction = false;
                    if (functionType->get_return_type()->unparseToString() == "ssize_t")
                       {
                         SgTypePtrList & argumentList = functionType->get_arguments();
                         SgTypePtrList::iterator i = argumentList.begin();
                         if ( (*i++)->unparseToString() == "int" )
                              if ( (*i++)->unparseToString() == "const void *" )
                                   if ( (*i++)->unparseToString() == "size_t" )
                                        if ( (*i++)->unparseToString() == "int" )
                                             foundFunction = true;
                       }

                    if (foundFunction == true)
                       {
                      // Now get the sysmbol using functionType
                         SgScopeStatement *scope = functionDeclaration->get_scope();
                         ROSE_ASSERT(scope != NULL);
                         functionSymbol = scope->lookup_function_symbol (functionName,functionType);
                       }
                  }
               break;
             }
          default:
             {
            // No other special cases
             }
        }
   }