void FortranAnalysis::visit(SgFunctionDefinition * func_def)
{
   SgFunctionDeclaration * func_decl = isSgFunctionDeclaration(func_def->get_declaration());
   if (func_decl == NULL) return;

   SgInitializedNamePtrList func_args = func_decl->get_parameterList()->get_args();
   SgInitializedNamePtrList::iterator arg = func_args.begin();

   //   for (it_args = func_args.begin(); it_args != func_args.end(); it_args++) {
   while (arg != func_args.end()) {
      SgInitializedName * func_arg = isSgInitializedName(*arg++);
      SgSymbol * sym = func_def->lookup_symbol(func_arg->get_name());
      SgType * type = sym->get_type();
      if (sym == NULL) {
         printf("FortranAnalysis::visit: no symbol for name %s\n",
                func_arg->get_name().getString().c_str());
      }
      else if (isSgArrayType(type) != NULL) {
         printf("WARNING: arg %s must be a scalar\n", func_arg->get_name().str());
         sym->setAttribute("dummy_attr", new AstTextAttribute("DUMMY_ARRAY_TYPE_ARG"));
      }
      else if (isSgNamedType(type)) {
         sym->setAttribute("dummy_attr", new AstTextAttribute("DUMMY_NAMED_TYPE_ARG"));
      }
      else {
         sym->setAttribute("dummy_attr", new AstTextAttribute("DUMMY_ARG"));
      }

      if (sym != NULL && isElementalArrayType(func_arg)) {
         sym->setAttribute("elemental_attr", new AstTextAttribute("ELEMENTAL_ARRAY"));
         sym->setAttribute("index_attr", new AstTextAttribute("idx"));
      }

      if (sym != NULL && hasArrayDescriptor(func_arg)) {
         sym->setAttribute("descriptor_attr", new AstTextAttribute("desc_"+func_arg->get_name()));
         sym->setAttribute("index_attr", new AstTextAttribute("idx_"+func_arg->get_name()));
      }
   }
}
Ejemplo n.º 2
0
void
DetectHiddenOriginalExpressionTreeTraversal::visit ( SgNode* node )
   {
  // We only want to search for original expression trees where they can be hidden.

     ROSE_ASSERT(node != NULL);

     SgArrayType* arrayType = isSgArrayType(node);
     if (arrayType != NULL)
        {
#if 0
          printf ("Found an array type arrayType = %p (looking for original expression tree) \n",arrayType);
#endif
          SgExpression* index = arrayType->get_index();
          if (index != NULL)
             {
               DetectOriginalExpressionTreeTraversal t;
               t.traverse(index,preorder);
             }
        }

#if 0
  // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression.
     SgVariableDefinition* variableDefinition = isSgVariableDefinition(node);
     if (variableDefinition != NULL)
        {
#if 0
          printf ("Found a SgVariableDefinition (looking for original expression tree) \n");
#endif
          SgExpression* bitfieldExp = variableDefinition->get_bitfield();
          if (bitfieldExp != NULL)
             {
               DetectOriginalExpressionTreeTraversal t;
               t.traverse(bitfieldExp,preorder);
             }
        }
#endif
   }
Ejemplo n.º 3
0
void
UnparseFortran_type::unparsePointerType(SgType* type, SgUnparse_Info& info, bool printAttrs)
{
#if 0
    // printf ("Inside of UnparserFort::unparsePointerType \n");
    // cur << "\n/* Inside of UnparserFort::unparsePointerType */\n";
    curprint ("\n! Inside of UnparserFort::unparsePointerType \n");
#endif

    // DQ (1/16/2011): Note that pointers in fortran are not expressed the same as in C/C++, are are
    // only a part of the type which is managed more directly using attributes in the variable declaration.
    // Not clear that we want to do anything here in the unparser...

    SgPointerType* pointer_type = isSgPointerType(type);
    ROSE_ASSERT(pointer_type != NULL);

#if 0
    /* special cases: ptr to array, int (*p) [10] */
    /*                ptr to function, int (*p)(int) */
    /*                ptr to ptr to .. int (**p) (int) */

    if (isSgReferenceType(pointer_type->get_base_type()) ||
            isSgPointerType(pointer_type->get_base_type()) ||
            isSgArrayType(pointer_type->get_base_type()) ||
            isSgFunctionType(pointer_type->get_base_type()) ||
            isSgMemberFunctionType(pointer_type->get_base_type()) ||
            isSgModifierType(pointer_type->get_base_type()) )
    {
        info.set_isPointerToSomething();
    }

    // If not isTypeFirstPart nor isTypeSecondPart this unparse call
    // is not controlled from the statement level but from the type level

    if (info.isTypeFirstPart() == true)
    {
        unparseType(pointer_type->get_base_type(), info);

        // DQ (9/21/2004): Moved this conditional into this branch (to fix test2004_93.C)
        // DQ (9/21/2004): I think we can assert this, and if so we can simplify the logic below
        ROSE_ASSERT(info.isTypeSecondPart() == false);

        curprint("*");
    }
    else
    {
        if (info.isTypeSecondPart() == true)
        {
            unparseType(pointer_type->get_base_type(), info);
        }
        else
        {
            SgUnparse_Info ninfo(info);
            ninfo.set_isTypeFirstPart();
            unparseType(pointer_type, ninfo);
            ninfo.set_isTypeSecondPart();
            unparseType(pointer_type, ninfo);
        }
    }
#else
    if (info.supressStrippedTypeName() == false)
    {
        // DQ (1/16/2011): We only want to output the name of the stripped type once!
        SgType* stripType = pointer_type->stripType();
        unparseType(stripType, info);
        info.set_supressStrippedTypeName();
    }

    curprint(type->get_isCoArray()? ", COPOINTER": ", POINTER");

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

#if 0
    // printf ("Leaving of UnparserFort::unparsePointerType \n");
    // cur << "\n/* Leaving of UnparserFort::unparsePointerType */\n";
    curprint ("\n! Leaving UnparserFort::unparsePointerType \n");
#endif
}
Ejemplo n.º 4
0
void ModelBuilder::add(Model::model_t & model, SgType * sg_type) {
  SgModifierType * modifier_type  = isSgModifierType(sg_type);
  if (modifier_type != NULL) {
    add(model, modifier_type->get_base_type());
    return;
  }

  Model::type_t element = Model::build<Model::e_model_type>();

  element->node->type = sg_type;

  SgNamedType     * named_type     = isSgNamedType(sg_type);
  SgArrayType     * array_type     = isSgArrayType(sg_type);
  SgPointerType   * pointer_type   = isSgPointerType(sg_type);
  SgReferenceType * reference_type = isSgReferenceType(sg_type);
  if (named_type != NULL) {
    SgClassType   * class_type   = isSgClassType(named_type);
    SgEnumType    * enum_type    = isSgEnumType(named_type);
    SgTypedefType * typedef_type = isSgTypedefType(named_type);

    SgDeclarationStatement * decl_stmt = named_type->get_declaration()->get_firstNondefiningDeclaration();
    assert(decl_stmt != NULL);
    SgSymbol * decl_sym = decl_stmt->get_symbol_from_symbol_table();
    assert(decl_sym != NULL);

    if (class_type != NULL) {
      element->node->kind = Model::node_t<Model::e_model_type>::e_class_type;

      SgClassSymbol * class_sym = isSgClassSymbol(decl_sym);
      assert(class_sym != NULL);
      element->node->base_class = model.lookup_class(class_sym);
      if (element->node->base_class == NULL) {
        add(model, class_sym);
        element->node->base_class = model.lookup_class(class_sym);
      }
      assert(element->node->base_class != NULL);
    }
    else if (enum_type != NULL) {
      element->node->kind = Model::node_t<Model::e_model_type>::e_enum_type;

      SgEnumSymbol * enum_sym = isSgEnumSymbol(decl_sym);
      assert(enum_sym != NULL);
      element->node->enum_symbol = enum_sym;
    }
    else if (typedef_type != NULL) {
      element->node->kind = Model::node_t<Model::e_model_type>::e_typedef_type;

      SgTypedefSymbol * typedef_sym = isSgTypedefSymbol(decl_sym);
      assert(typedef_sym != NULL);
      element->node->typedef_symbol = typedef_sym;

      element->node->base_type = model.lookup_type(typedef_type->get_base_type());
      if (element->node->base_type == NULL) {
        add(model, typedef_type->get_base_type());
        element->node->base_type = model.lookup_type(typedef_type->get_base_type());
      }
      assert(element->node->base_type != NULL);
    }
    else assert(false);
  }
  else if (array_type != NULL) {
    element->node->kind = Model::node_t<Model::e_model_type>::e_array_type;

    element->node->base_type = model.lookup_type(array_type->get_base_type());
    if (element->node->base_type == NULL) {
      add(model, array_type->get_base_type());
      element->node->base_type = model.lookup_type(array_type->get_base_type());
    }
    assert(element->node->base_type != NULL);
  }
  else if (pointer_type != NULL) {
    element->node->kind = Model::node_t<Model::e_model_type>::e_pointer_type;

    element->node->base_type = model.lookup_type(pointer_type->get_base_type());
    if (element->node->base_type == NULL) {
      add(model, pointer_type->get_base_type());
      element->node->base_type = model.lookup_type(pointer_type->get_base_type());
    }
    assert(element->node->base_type != NULL);
  }
  else if (reference_type != NULL) {
    element->node->kind = Model::node_t<Model::e_model_type>::e_reference_type;

    element->node->base_type = model.lookup_type(reference_type->get_base_type());
    if (element->node->base_type == NULL) {
      add(model, reference_type->get_base_type());
      element->node->base_type = model.lookup_type(reference_type->get_base_type());
    }
    assert(element->node->base_type != NULL);
  }
  else {
    element->node->kind = Model::node_t<Model::e_model_type>::e_native_type;
  }
  
  element->scope->parent.a_namespace = NULL; /// \todo

  model.types.push_back(element);
}
Ejemplo n.º 5
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
}
Ejemplo n.º 6
0
// DQ (4/7/2004): Added to support more general lookup of data in the AST (vector of variants)
void* querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVector targetVariantVector,  NodeQuerySynthesizedAttributeType* returnNodeList )
   {
  // This function extracts type nodes that would not be traversed so that they can
  // accumulated to a list.  The specific nodes collected into the list is controlled
  // by targetVariantVector.

     ROSE_ASSERT (astNode != NULL);

#if 0
     printf ("Inside of void* querySolverGrammarElementFromVariantVector() astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     Rose_STL_Container<SgNode*> nodesToVisitTraverseOnlyOnce;

     pushNewNode (returnNodeList,targetVariantVector,astNode);

     vector<SgNode*>               succContainer      = astNode->get_traversalSuccessorContainer();
     vector<pair<SgNode*,string> > allNodesInSubtree  = astNode->returnDataMemberPointers();

#if 0
     printf ("succContainer.size()     = %zu \n",succContainer.size());
     printf ("allNodesInSubtree.size() = %zu \n",allNodesInSubtree.size());
#endif

     if ( succContainer.size() != allNodesInSubtree.size() )
        {
          for (vector<pair<SgNode*,string> >::iterator iItr = allNodesInSubtree.begin(); iItr!= allNodesInSubtree.end(); ++iItr )
             {
#if 0
               if ( iItr->first != NULL  )
                  {
                 // printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str());
                    printf ("iItr->first = %p \n",iItr->first);
                    printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str());
                  }
#endif
            // DQ (7/27/2014): Check if this is always non-NULL.
            // ROSE_ASSERT(iItr->first != NULL);
#if 0
               if (iItr->first != NULL)
                  {
                 // printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d class_name = %s \n",iItr->first->variantT(),iItr->first->class_name().c_str());
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first             = %p \n",iItr->first);
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->class_name = %s \n",iItr->first->class_name().c_str());
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d \n",(int)iItr->first->variantT());
                  }
                 else
                  {
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first == NULL \n");
                  }
#endif
               SgType* type = isSgType(iItr->first);
               if ( type != NULL  )
                  {
                 // DQ (1/13/2011): If we have not already seen this entry then we have to chase down possible nested types.
                 // if (std::find(succContainer.begin(),succContainer.end(),iItr->first) == succContainer.end() )
                    if (std::find(succContainer.begin(),succContainer.end(),type) == succContainer.end() )
                       {
                      // DQ (1/30/2010): Push the current type onto the list first, then any internal types...
                         pushNewNode (returnNodeList,targetVariantVector,type);

                      // Are there any other places where nested types can be found...?
                      // if ( isSgPointerType(iItr->first) != NULL  || isSgArrayType(iItr->first) != NULL || isSgReferenceType(iItr->first) != NULL || isSgTypedefType(iItr->first) != NULL || isSgFunctionType(iItr->first) != NULL || isSgModifierType(iItr->first) != NULL)
                      // if (type->containsInternalTypes() == true)
                         if (type->containsInternalTypes() == true)
                            {
#if 0
                              printf ("If we have not already seen this entry then we have to chase down possible nested types. \n");
                           // ROSE_ASSERT(false);
#endif

                              Rose_STL_Container<SgType*> typeVector = type->getInternalTypes();
#if 0
                              printf ("----- typeVector.size() = %zu \n",typeVector.size());
#endif
                              Rose_STL_Container<SgType*>::iterator i = typeVector.begin();
                              while(i != typeVector.end())
                                 {
#if 0
                                   printf ("----- internal type = %s \n",(*i)->class_name().c_str());
#endif
                                // DQ (1/16/2011): This causes a test in tests/roseTests/programAnalysisTests/variableLivenessTests 
                                // to fail with error "Error :: Number of nodes = 37  should be : 36"

                                // Add this type to the return list of types.
                                   pushNewNode (returnNodeList,targetVariantVector,*i);

                                   i++;
                                 }
                            }

                      // DQ (1/30/2010): Move this code to the top of the basic block.
                      // pushNewNode (returnNodeList,targetVariantVector,iItr->first);
                      // pushNewNode (returnNodeList,targetVariantVector,type);
                       }
                  }
             }
        }

#if 0
    // This code cannot be put here. Since the same SgVarRefExp will also be found during variable substitution phase.
    // We don't want to replace the original SgVarRefExp!!
    // Liao 1/19/2011. query the dim_info of SgArrayType associated with SgPntrArrRefExp
    // e.g.  assuming a subtree has a reference to an array, then the variables used to declare the array dimensions should also be treated as referenced/used by the subtree
    // even though the reference is indirect. 
    // AST should look like: 
    //    SgPntrArrRefExp -> SgVarRefExp (lhs) -> SgVariableSymbol(symbol) -> SgInitializedName -> SgArrayType (typeptr)  -> SgExprListExp (dim_info)
    // AST outlining needs to find indirect use of a variable to work properly
    if (std::find(targetVariantVector.begin(), targetVariantVector.end(), V_SgVarRefExp) != targetVariantVector.end())
    // Only do this if SgVarRefExp is of interest
    { 
      if (SgPntrArrRefExp * arr_exp = isSgPntrArrRefExp(astNode))
      {
        printf("Debug: queryVariant.C Found SgPntrArrRefExp :%p\n", arr_exp);
        Rose_STL_Container<SgNode*> refList = NodeQuery::querySubTree(arr_exp->get_lhs_operand(),V_SgVarRefExp);
        // find the array reference from the lhs operand, which could be a complex arithmetic expression
        SgVarRefExp* array_ref = NULL; 
        for (Rose_STL_Container<SgNode*>::iterator iter = refList.begin(); iter !=refList.end(); iter ++)
        {
          SgVarRefExp* cur_ref = isSgVarRefExp(*iter);
          ROSE_ASSERT (cur_ref != NULL);
          SgVariableSymbol * sym = cur_ref->get_symbol();
          ROSE_ASSERT (sym != NULL);
          SgInitializedName * i_name = sym->get_declaration();
          ROSE_ASSERT (i_name != NULL);
          SgArrayType * a_type = isSgArrayType(i_name->get_typeptr());
          if (a_type)
          {
            Rose_STL_Container<SgNode*> dim_ref_list = NodeQuery::querySubTree(a_type->get_dim_info(),V_SgVarRefExp);
            for (Rose_STL_Container<SgNode*>::iterator iter2 = dim_ref_list.begin(); iter2 != dim_ref_list.end(); iter2++)
            {
              SgVarRefExp* dim_ref = isSgVarRefExp(*iter2); 
              printf("Debug: queryVariant.C Found indirect SgVarRefExp as part of array dimension declaration:%s\n", dim_ref->get_symbol()->get_name().str());
              pushNewNode (returnNodeList, targetVariantVector, *iter2);
            }

          }  

        }
      } // end if SgPntrArrRefExp
    } // end if find()
#endif
     return NULL;
   } /* End function querySolverUnionFields() */
Ejemplo n.º 7
0
  //! Return an expression like 8*sizeof(int)+ 3*sizeof(float) + 5*sizeof(double) for a list of variables accessed (either read or write)
  // For array variable, we should only count a single element access, not the entire array size
  // Algorithm:  
  //   Iterate on each variable in the set
  //     group them into buckets based on types, using a map<SgType*, int> to store this
  //   Iterate the list of buckets to generate count*sizeof(type) + .. expression 
  SgExpression* calculateBytes (std::set<SgInitializedName*>& name_set, SgScopeStatement* scope, bool isRead)
  {
    SgExpression* result = NULL; 
    if (name_set.size()==0) return result;

   // the input is essentially the loop body, a scope statement
   ROSE_ASSERT (scope != NULL);
    // We need to record the associated loop info.
    SgStatement* loop= NULL;
    SgForStatement* forloop = isSgForStatement(scope->get_scope());
    SgFortranDo* doloop = isSgFortranDo(scope->get_scope());

    if (forloop)
      loop = forloop;
    else if (doloop)
      loop = doloop;
    else
    {
      cerr<<"Error in CountLoadStoreBytes (): input is not loop body type:"<< scope->class_name()<<endl;
      assert(false);
    }   

    std::map<SgType* , int> type_based_counters; 

   // get all processed variables by inner loops
    std::set<SgInitializedName*> processed_var_set; 
    getVariablesProcessedByInnerLoops (scope, isRead, processed_var_set);
    
    // fill in the type-based counters
    std::set<SgInitializedName*>::iterator set_iter; 
    for (set_iter = name_set.begin(); set_iter != name_set.end(); set_iter++)
    {
      SgInitializedName* init_name = *set_iter; 
      // skip visited variable when processing inner loops
      // some global variables may be visited by another function
      // But we should count it when processing the current function!
      //
      // We group all references to a same variable into one reference for now
      // if a variable is considered when processing inner loops, the variable
      // will be skipped when processing outer loops.
      if (isRead)
      {
         // if inner loops already processed it, skip it
        if (processed_var_set.find(init_name) != processed_var_set.end())
          continue; 
        else
          LoopLoadVariables[loop].insert(init_name); 
      }
      else
      {
        if (processed_var_set.find(init_name) != processed_var_set.end())
          continue; 
        else
          LoopStoreVariables[loop].insert(init_name); 
      }
      // It is tricky here, TODO consider pointer, typedefs, reference, modifier types
      SgType* stripped_type = (*set_iter)->get_type()->stripTypedefsAndModifiers();
      SgType* base_type = NULL; 
      if (isScalarType(stripped_type))
        base_type = stripped_type;
      else if (isSgArrayType(stripped_type))
      {  // we may have multi-dimensional arrays like int a[][][];
        base_type = stripped_type; 
        do {
         base_type = isSgArrayType(base_type)->get_base_type(); 
        } while (isSgArrayType (base_type));
      }
      else 
      {
        cerr<<"Error in calculateBytes(). Unhandled stripped type:"<<stripped_type->class_name()<<endl;
        assert (false);
      }

      type_based_counters[base_type] ++; 
    } // end for

    // use the type-based counters for byte calculation
    std::map<SgType* , int>::iterator citer; 
    //It is possible now to have zero after filtering out redundant variables
    //assert (type_based_counters.size()>0);
    for (citer = type_based_counters.begin(); citer !=type_based_counters.end(); citer ++)
    {
      SgType* t = (*citer).first;
      // at this point, we should not have array types any more
      ROSE_ASSERT (isSgArrayType (t) == false); 
      int count = (*citer).second; 
      assert (t != NULL);
      assert (count>0);
      SgExpression* sizeof_exp = NULL; 
      if (is_Fortran_language())
      {
#if 0  // this does not work. cannot find func symbol for sizeof()       
      // In Fortran sizeof() is a function call, not  SgSizeOfOp.
      // type name is a variable in the AST, 
      // Too much trouble to build 
        assert (scope !=NULL);
        // This does not work
        //SgFunctionSymbol* func_sym = lookupFunctionSymbolInParentScopes(SgName("sizeof"), scope);
        SgGlobal* gscope = getGlobalScope (scope);
        assert (gscope !=NULL);
        SgFunctionSymbol* func_sym = gscope->lookup_function_symbol(SgName("sizeof"));
        assert (func_sym!=NULL);
        SgVarRefExp* type_var = buildVarRefExp( t->unparseToString(), scope );
        assert (type_var !=NULL);
        sizeof_exp = buildFunctionCallExp (func_sym, buildExprListExp(type_var));
#else
        // sizeof is not an operator in Fortran, there is no unparsing support for this
        // sizeof_exp = buildSizeOfOp(t);
        // Directly obtain an integer size value
        sizeof_exp = buildIntVal(getSizeOf(t));
#endif         
      }
      else if (is_C_language() || is_C99_language() || is_Cxx_language())
      {
        sizeof_exp = buildSizeOfOp(t);
      }
      else
      {
        cerr<<"Error in calculateBytes(). Unsupported programming language other than C/Cxx and Fortran. "<<endl;
        assert (false);
      }
      SgExpression* mop = buildMultiplyOp(buildIntVal(count), sizeof_exp);
       if (result == NULL)
         result = mop; 
       else 
         result = buildAddOp(result, mop);
    }
    return result; 
  }  
Ejemplo n.º 8
0
/*
 * Add calls to register and unregister expressions/arrays with the memory
 * management wrapper.
 */
bool RegisterPointers::addRegUnregCalls()
{
	string msg;

	if(definedInSystemHeader)
	{
		msg = "\t\t\tVariable " + NAME(varSymbol) + " is in system headers";
		WARNING(TOOL, msg);
		return false;
	}

	if(compilerGenerated)
	{
		msg = "\t\t\tVariable " + NAME(varSymbol) + " is compiler-generated";
		WARNING(TOOL, msg);
		return false;
	}

	if(addrUsedInIO)
	{
		msg = "\t\t\tVariable " + NAME(varSymbol) + " has its address taken in "
				+ "a function known to not require registering/unregistering";
		WARNING(TOOL, msg);
		return false;
	}

	//Add register/unregister calls
	SgStatement* prevStmt = NULL;
	SgExprStatement* funcCall = NULL;
	SgType* type = NULL;
	SgExpression* expr = NULL;

	if(isGlobal)
	{
		type = varName->get_type();
		SgName name = varName->get_name();
		int numVals = 1;

		if(isSgPointerType(type))
			return false;	//If its a pointer, it points to a static array, dynamic array, or scalar
							//which has its address taken (all of which have already been registered)

		SgFunctionDeclaration* main = findMain(getScope(varName));
		ROSE_ASSERT(main);
		expr = buildVarRefExp(name, varName->get_scope());
		if(isSgArrayType(type))
			numVals = getArrayElementCount(isSgArrayType(type));
		else
			expr = buildAddressOfOp(expr);

		funcCall = MMCallBuilder::buildRegisterPointerCall(expr, buildUnsignedIntVal(numVals),
				main->get_definition());
		insertStatement(getFirstStatement(main->get_definition()), funcCall);//, false, true);
		funcCall = MMCallBuilder::buildUnregisterPointerCall(expr, main->get_definition());
		instrumentEndOfFunction(main, funcCall);
	}
	else if(expression) //Address-of expressions
	{
		prevStmt = getEnclosingStatement(expression);
		funcCall = MMCallBuilder::buildRegisterPointerCall(expression, buildUnsignedIntVal(1),
				getScope(expression));
		insertStatement(prevStmt, funcCall);
		funcCall = MMCallBuilder::buildUnregisterPointerCall(expression, getScope(expression));
		instrumentEndOfFunction(getEnclosingFunctionDeclaration(prevStmt), funcCall);
	}
	else //Array types
	{
		SgVarRefExp* varRef = buildVarRefExp(varName, getScope(varName));

		int numVals = getArrayElementCount(isSgArrayType(varName->get_type()));
		funcCall = MMCallBuilder::buildRegisterPointerCall(varRef, buildUnsignedIntVal(numVals),
				varName->get_scope());
		insertStatement(varName->get_declaration(), funcCall, false, true);
		varRef = buildVarRefExp(varName, getScope(varName));
		funcCall = MMCallBuilder::buildUnregisterPointerCall(varRef, varName->get_scope());
		instrumentEndOfFunction(getEnclosingFunctionDeclaration(varName), funcCall);
	}

	return true;
}
Ejemplo n.º 9
0
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);
   }
Ejemplo n.º 10
0
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);
   }
Ejemplo n.º 11
0
void
VerifyOriginalExpressionTreesSetToNull::visit ( SgNode* node )
   {
  // This traversal is used to verify that all of the original expression trees in the AST have
  // been either deleted (optional) or used to replace the constant folded values (the default
  // for the ROSE AST so that we can preserve the greatest amount of source-to-source detail).

  // Note that it can detect problems that are due to orphaned expressions in the AST.
  // An example is test2011_138.C where the multidimensional array indexing causes and orphaned 
  // expression to be created and it has a original expression tree.  Since the orphaned expression 
  // can't be reached we can eliminate the original expression tree.  The bug in ROSE is that there
  // is an orphaned expression tree not that there is a remaining original expression tree.

  // We need a mechanism to detect nodes that exist in the AST and are not pointed to by any other 
  // IR node (and then we have to decide if parent pointers count).

     ROSE_ASSERT(node != NULL);

  // printf ("In VerifyOriginalExpressionTreesSetToNull::visit(): node = %s \n",node->class_name().c_str());

     SgExpression* exp = isSgExpression(node);
     if (exp != NULL)
        {
          SgExpression* originalExpressionTree = exp->get_originalExpressionTree();

          if (originalExpressionTree != NULL)
             {
#ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION
               printf ("Error: there is a valid originalExpressionTree = %p = %s on node = %p = %s \n",originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str());
#endif
             }
#if 0 // Liao debugging 11/13/2012
          ROSE_ASSERT(originalExpressionTree == NULL);
#endif

       // Allow us to ignore the cases of originalExpressionTrees hidden in array types.
       // I want to narrow down the failing tests codes to eliminate this case which is handled separately.

          if (originalExpressionTree != NULL)
             {
#if 0
               SgNode* parent = exp;

            // Note that test2011_121.C fails to be either a SgArrayType or a SgVariableDefinition (failing in some part of "complex" header file).
            // test2005_203.C demonstrates the use of constant folding in bitfield specifications.
            // while (parent != NULL && isSgArrayType(parent) == NULL) 
               while (parent != NULL && isSgArrayType(parent) == NULL && isSgVariableDefinition(parent) == NULL) 
                  {
                    parent = parent->get_parent();
                  }

               if (isSgArrayType(parent) == NULL)
                  {
                    printf ("So what is the parent: parent = %p = %s \n",parent, (parent != NULL) ? parent->class_name().c_str() : "NULL");
                  }
               ROSE_ASSERT(isSgArrayType(parent) != NULL || isSgVariableDefinition(parent) != NULL);
#else
#ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION
               printf ("In VerifyOriginalExpressionTreesSetToNull(): originalExpressionTree = %p = %s on node = %p = %s Ingoring originalExpressionTree != NULL \n",
                    originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str());
#endif
#endif
             }
        }
   }
Ejemplo n.º 12
0
Archivo: DCL.C Proyecto: 8l/rose
/**
 * 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;
}
Ejemplo n.º 13
0
void
RemoveConstantFoldedValueViaParent::visit ( SgNode* node )
   {
  // This is an alternative implementation that allows us to handle expression that are not 
  // traversed in the AST (e.g. types like SgArrayType which can contain expressions).

     ROSE_ASSERT(node != NULL);

  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
#if 0
     printf ("In RemoveConstantFoldedValueViaParent::visit(): node = %p = %s \n",node,node->class_name().c_str());
#endif

  // DQ (10/12/2012): Turn this on so that we can detect failing IR nodes (failing later) that have valid originalExpressionTrees.
  // DQ (10/12/2012): Turn this back off because it appears to fail...
#if 0
     SgExpression* exp = isSgExpression(node);
     if (exp != NULL)
        {
          SgExpression* originalExpressionTree = exp->get_originalExpressionTree();
          if (originalExpressionTree != NULL)
             {
               SgNode* parent = exp->get_parent();
               if (parent != NULL)
                  {
                    printf ("Current IR node with SgExpression parent = %p = %s child = %p = %s originalExpressionTree = %p = %s \n",parent,parent->class_name().c_str(),node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str());
                    bool traceReplacement = true;
                    ConstantFoldedValueReplacer r(traceReplacement, exp);
                    parent->processDataMemberReferenceToPointers(&r);
                 // node->processDataMemberReferenceToPointers(&r);
                  }

            // Set the originalExpressionTree to NULL.
               exp->set_originalExpressionTree(NULL);

            // Set the parent of originalExpressionTree to be the parent of exp.
               originalExpressionTree->set_parent(parent);

            // And then delete the folded constant.
               SageInterface::deleteAST(exp);
             }
        }
#endif

     SgArrayType* arrayType = isSgArrayType(node);
     if (arrayType != NULL)
        {
#if 0
          printf ("Found an array type arrayType = %p arrayType->get_index() = %p \n",arrayType,arrayType->get_index());
#endif
          SgExpression* index = arrayType->get_index();
          if (index != NULL)
             {
#if 0
               printf ("Fixup array index = %p = %s (traverse index AST subtree) \n",index,index->class_name().c_str());
#endif
               RemoveConstantFoldedValue astFixupTraversal;
               astFixupTraversal.traverse(index);
#if 0
               printf ("DONE: Fixup array index = %p (traverse index AST) \n\n\n\n",index);
#endif
#if 0
               printf ("Found an array index = %p (fixup index directly) \n",index);
#endif
            // Handle the case where the original expression tree is at the root of the subtree.
               SgExpression* originalExpressionTree = index->get_originalExpressionTree();
               if (originalExpressionTree != NULL)
                  {
#if 0
                    printf ("Found an originalExpressionTree in the array index originalExpressionTree = %p \n",originalExpressionTree);
#endif
                 // DQ (6/12/2013): This appears to be a problem in EDG 4.7 (see test2011_117.C).
                    std::vector<SgExpression*> redundantChainOfOriginalExpressionTrees;
                    if (originalExpressionTree->get_originalExpressionTree() != NULL)
                       {
#if 0
                         printf ("Detected originalExpressionTree nested directly within the originalExpressionTree \n",
                              originalExpressionTree,originalExpressionTree->class_name().c_str(),
                              originalExpressionTree->get_originalExpressionTree(),originalExpressionTree->get_originalExpressionTree()->class_name().c_str());
#endif
                      // Loop to the end of the chain of original expressions (which EDG 4.7 should never have constructed).
                         while (originalExpressionTree->get_originalExpressionTree() != NULL)
                            {
#if 0
                              printf ("Looping through a chain of originalExpressionTrees \n");
#endif
                           // Save the list of redundnat nodes so that we can delete them properly.
                              redundantChainOfOriginalExpressionTrees.push_back(originalExpressionTree);

                              originalExpressionTree = originalExpressionTree->get_originalExpressionTree();
                            }
#if 0
                         printf ("Exiting as a test! \n");
                         ROSE_ASSERT(false);
#endif
                       }

                    arrayType->set_index(originalExpressionTree);
                    originalExpressionTree->set_parent(arrayType);

                    index->set_originalExpressionTree(NULL);

                 // printf ("DEBUGING: skip delete of index in array type \n");
                    delete index;

                 // DQ (6/12/2013): Delete the nodes that we had to skip over (caused by chain of redundant entries from EDG 4.7).
                    std::vector<SgExpression*>::iterator i = redundantChainOfOriginalExpressionTrees.begin();
                    while (i != redundantChainOfOriginalExpressionTrees.end())
                       {
#if 0
                         printf ("deleting the redundnat originalExpressionTree chain caused by EDG 4.7 (delete %p = %s) \n",*i,(*i)->class_name().c_str());
#endif
                         delete *i;
                         i++;
                       }

                    index = NULL;
                  }
             }
        }

     SgVariableDefinition* variableDefinition = isSgVariableDefinition(node);
     if (variableDefinition != NULL)
        {
#if 0
          printf ("Found a SgVariableDefinition \n");
#endif
          SgExpression* bitfieldExp = variableDefinition->get_bitfield();
          if (bitfieldExp != NULL)
             {
#if 0
               printf ("Fixup bitfieldExp = %p (traverse bitfieldExp AST subtree) \n",bitfieldExp);
#endif
               RemoveConstantFoldedValue astFixupTraversal;
               astFixupTraversal.traverse(bitfieldExp);

            // Handle the case where the original expression tree is at the root of the subtree.
               SgExpression* originalExpressionTree = bitfieldExp->get_originalExpressionTree();
               if (originalExpressionTree != NULL)
                  {
#if 0
                 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression.
                    variableDefinition->set_bitfield(originalExpressionTree);
                    originalExpressionTree->set_parent(variableDefinition);

                    bitfieldExp->set_originalExpressionTree(NULL);
                    delete bitfieldExp;
                    bitfieldExp = NULL;
#else
                 // The ROSE AST needs to be fixed to handle more general expressions for bitfield widths (this does not effect the CFG).
                 // TODO: Change the data type of the bitfield data member in SgVariableDefinition.

                 // DQ (1/20/2014): This has been done now.
                 // printf ("Member data bitfield widths need to be changed (in the ROSE IR) to support more general expressions (can't fix this original expression tree) \n");
#endif
#if 0
                 // This case is not handled yet!
                    printf ("Found an original expression tree in a bitfield expression \n");
                    ROSE_ASSERT(false);
#endif
                  }
             }
        }
   }
Ejemplo n.º 14
0
/*!
 *  \brief Creates a new outlined-function parameter for a given
 *  variable. The requirement is to preserve data read/write semantics.
 *
 *  For C/C++: we use pointer dereferencing to implement pass-by-reference
 *    In a recent implementation, side effect analysis is used to find out
 *    variables which are not modified so pointer types are not used.
 *

 *
 *  Given a variable (i.e., its type and name) whose references are to
 *  be outlined, create a suitable outlined-function parameter. 
 *  For C/C++, the  parameter is created as a pointer, to support parameter passing of
 *  aggregate types in C programs. 
 *  Moreover, the type is made 'void' if the base type is not a primitive type.
 *   
 *  An original type may need adjustments before we can make a pointer type from it.
 *  For example: 
 *    a)Array types from a function parameter: its first dimension is auto converted to a pointer type 
 *
 *    b) Pointer to a C++ reference type is illegal, we create a pointer to its
 *    base type in this case. It also match the semantics for addressof(refType) 
 *
 * 
 *  The implementation follows two steps:
 *     step 1: adjust a variable's base type
 *     step 2: decide on its function parameter type
 *  Liao, 8/14/2009
 */
static OutlinedFuncParam_t createParam (const SgInitializedName* i_name, bool readOnly=false)
{

  ROSE_ASSERT (i_name);
  SgType* init_type = i_name->get_type();
  ROSE_ASSERT (init_type);

  // Stores the real parameter type to be used in new_param_type
  string init_name = i_name->get_name ().str (); 

  SgType* param_base_type;
  //has to be not scalar                                                                                                                                              
  if(isSgArrayType (init_type) ){

    SgType* base_type = init_type->findBaseType();
    param_base_type = buildPointerType(base_type);
  }
  else if (isSgPointerType (init_type))
    {
      //Didem, this used to be 2 but I changed into 0. Didn't make any sense
      init_name = init_name.substr(0);
      //Didem: I have changed the types into 1D pointer type 
      SgType* base_type = init_type->findBaseType();
      param_base_type = buildPointerType(base_type);

      //param_base_type = init_type;
    }
  else{
    param_base_type = init_type;
  }

   // The parameter name reflects the type: the same name means the same type, 
   // p__ means a pointer type
  string new_param_name = init_name;
  SgType* new_param_type = NULL;

  // For classic behavior, read only variables are passed by values for C/C++
  // They share the same name and type
  if (Outliner::enable_classic) 
  { 
    // read only parameter: pass-by-value, the same type and name
    // shared parameters  : already pointer type 
    //if (readOnly)
    {

      new_param_type = param_base_type;
    }
    /*
    else
    {
      new_param_name= "d__" + new_param_name;
      new_param_type = SgPointerType::createType (param_base_type);

      }*/
  }
  else // very conservative one, assume the worst side effects (all are written) 
  {
    new_param_name= new_param_name;
  }

  // So use base type directly
  // C/C++ parameters will use their new param type to implement pass-by-reference

  return OutlinedFuncParam_t (new_param_name, new_param_type);
}
Ejemplo n.º 15
0
bool Type::isArray() const {
	return isSgArrayType(t_) != 0;
}
Ejemplo n.º 16
0
std::string getSgInitializedName(SgInitializedName* initName) {
	std::string exprStr;
	SgSymbol* initNameSym = initName->search_for_symbol_from_symbol_table();
	std::string varInit = initializeVariable(initName);
	std::string retString;
	if (initName->get_initptr() != NULL) {
		SgInitializer* nameInitializer = initName->get_initializer();

	        VariantT var = nameInitializer->variantT();
        
		switch (var) {
                	case V_SgAggregateInitializer:
			{
				SgAggregateInitializer* aggInit = isSgAggregateInitializer(nameInitializer);
				if (!isSgArrayType(aggInit->get_type())) {
					std::cout << "currently only arrays use aggregate initializers, you are using " << aggInit->class_name() << std::endl;
					ROSE_ASSERT(false);
				}
				SgExprListExp* members = aggInit->get_initializers();
				SgExpressionPtrList member_expressions = members->get_expressions();
				std::string symName = SymbolToZ3[initNameSym];
				ROSE_ASSERT(SymbolToInstances[initNameSym] == 0);
				int arrmem = 0;
				std::stringstream exprStream;
				for (SgExpressionPtrList::iterator i = member_expressions.begin(); i != member_expressions.end(); i++) {
			
			exprStream << "\n(assert (= (select " << symName << "_0 "  << arrmem << ") " << getSgExpressionString((isSgAssignInitializer((*i))->get_operand())) << ")";
				arrmem = arrmem+1;
				}
                       		retString = varInit + "\n" + exprStream.str(); 
				#ifdef ARRAY_TEST
				std::cout << "retString: " << retString << std::endl;
				#endif
			
			break;
			}
			case V_SgCompoundInitializer:
			{	
			std::cout << "SgCompoundInitializer not yet supported" << std::endl;
			ROSE_ASSERT(false);
			break;
			}
			case V_SgConstructorInitializer:
			{
			std::cout << "SgConstructorInitializer is not yet supported" << std::endl;
			ROSE_ASSERT(false);
			break;
			}
			case V_SgDesignatedInitializer:
			{
			std::cout << "SgDesignatedInitializer is not yet supported" << std::endl;
			ROSE_ASSERT(false);
			break;
			}
			case V_SgAssignInitializer:
			{
			SgAssignInitializer* assignInit = isSgAssignInitializer(nameInitializer);
			std::string symName = SymbolToZ3[initNameSym];
			ROSE_ASSERT(SymbolToInstances[initNameSym] == 0);
			exprStr = "(assert (= " + symName + "_0 " + getSgExpressionString(assignInit->get_operand()) + "))";
			retString = varInit + "\n" + exprStr;
			break;
			}
			default:
			{
			std::cout << "unknown initializer of type: " << nameInitializer->class_name() << std::endl;
			ROSE_ASSERT(false);
			break;
			}
	}
			
		
	}		
	else {
		retString = varInit;
	}
	
	return retString;
}
Ejemplo n.º 17
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();
}
Ejemplo n.º 18
0
std::string initializeVariable(SgInitializedName* initName) {
	//if array type we need to get the index expression
	std::string index_expression_string;
	std::stringstream nameStringStream;
	SgName initNameName = initName->get_qualified_name();
	SgSymbol* initNameSym = initName->search_for_symbol_from_symbol_table();
	if (variablesOfNameX.find(initNameName.getString()) == variablesOfNameX.end()) {
		nameStringStream << initNameName.getString() << "_0";
		variablesOfNameX[initNameName.getString()] = 1;
	}
	else {
		int occurrence = variablesOfNameX[initNameName.getString()];
		nameStringStream << initNameName.getString() << "_" << occurrence;
		variablesOfNameX[initNameName.getString()] = occurrence+1;
	}
	SymbolToZ3[initNameSym] = nameStringStream.str();
	SymbolToInstances[initNameSym] = 0;
	SgType* initNameType = initName->get_type();
	std::string typeZ3;
	if (initNameType->isIntegerType()) {
		typeZ3 = "Int";
	}
	else if (initNameType->isFloatType()) {
		typeZ3 = "Real";
	}
	else if (isSgArrayType(initNameType)) {
		SgArrayType* arrTyp = isSgArrayType(initNameType);
		ROSE_ASSERT(arrTyp != NULL);
		SgType* underlying_type = arrTyp->get_base_type();
		std::string array_typeZ3;
		if (underlying_type->isIntegerType()) {
			array_typeZ3 = "Int";
		}
		else if (underlying_type->isFloatType()) {
			array_typeZ3 = "Real";
		}
		else {
			std::cout << "unknown underlying type of array!" << std::endl;
			std::cout << underlying_type->class_name() << std::endl;
			ROSE_ASSERT(false);
		}
		SgExpression* ind = arrTyp->get_index();
		std::stringstream arrStr;
		index_expression_string = getSgExpressionString(ind);
		typeZ3 = "(Array Int " + array_typeZ3 + ")";
	}
	else if (isSgClassType(initNameType)) {
		
		std::cout << "structs are not yet implemented" << std::endl;
		ROSE_ASSERT(false);
	}
	else if (isSgPointerType(initNameType)) {
		std::cout << "pointers are not yet implemented" << std::endl;
		ROSE_ASSERT(false);
	}
	else if (isSgEnumType(initNameType)) {
		SgEnumType* et = isSgEnumType(initNameType);
		SgEnumDeclaration* enum_d = isSgEnumDeclaration(et->getAssociatedDeclaration());
		getSgDeclarationStatement(enum_d);	
		typeZ3 = et->get_name().getString(); 
	}
	else {
		std::cout << "unknown type: " << initNameType->class_name() << std::endl;
		ROSE_ASSERT(false);
	}		
	std::string name = nameStringStream.str() + "_0";
	std::stringstream streamZ3;
	if (isSgArrayType(initNameType)) {
	streamZ3 << "(declare-const " << name << " " << typeZ3 << ")";
	streamZ3 << "\n(declare-fun " << name << "_len () Int)";
	streamZ3 << "\n(assert (= " << name << "_len " << index_expression_string << "))"; 	
	#ifdef ARRAY_TEST
	std::cout << "arrStream: " << streamZ3.str() << std::endl;
	#endif

	}
	else if (isSgEnumType(initNameType)) {
		streamZ3 << "(declare-const " << name << " " << typeZ3 << ")";
	}
	else {
	streamZ3 << "(declare-fun " << name << " () " << typeZ3 << ")";
	}
	return streamZ3.str();
}