Ejemplo n.º 1
0
SgClassDeclaration*
buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope)
   {
  // This function builds a class declaration and definition 
  // (both the defining and nondefining declarations as required).

  // Build a file info object marked as a transformation
     Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
     assert(fileInfo != NULL);

  // This is the class definition (the fileInfo is the position of the opening brace)
     SgClassDefinition* classDefinition   = new SgClassDefinition(fileInfo);
     assert(classDefinition != NULL);

  // Set the end of construct explictly (where not a transformation this is the location of the closing brace)
     classDefinition->set_endOfConstruct(fileInfo);

  // This is the defining declaration for the class (with a reference to the class definition)
     SgClassDeclaration* classDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition);
     assert(classDeclaration != NULL);

  // Set the defining declaration in the defining declaration!
     classDeclaration->set_definingDeclaration(classDeclaration);

  // Set the non defining declaration in the defining declaration (both are required)
     SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL);
     assert(classDeclaration != NULL);
     nondefiningClassDeclaration->set_scope(scope);
     nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration));

  // Set the internal reference to the non-defining declaration
     classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     classDeclaration->set_type(nondefiningClassDeclaration->get_type());

  // Set the defining and no-defining declarations in the non-defining class declaration!
     nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     nondefiningClassDeclaration->set_definingDeclaration(classDeclaration);

  // Set the nondefining declaration as a forward declaration!
     nondefiningClassDeclaration->setForward();

  // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)!
     classDefinition->set_declaration(classDeclaration);

  // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!)
     classDeclaration->set_scope(scope);

  // some error checking
     assert(classDeclaration->get_definingDeclaration() != NULL);
     assert(classDeclaration->get_firstNondefiningDeclaration() != NULL);
     assert(classDeclaration->get_definition() != NULL);

  // DQ (9/8/2007): Need to add function symbol to global scope!
     printf ("Fixing up the symbol table in scope = %p = %s for class = %p = %s \n",scope,scope->class_name().c_str(),classDeclaration,classDeclaration->get_name().str());
     SgClassSymbol* classSymbol = new SgClassSymbol(classDeclaration);
     scope->insert_symbol(classDeclaration->get_name(),classSymbol);
     ROSE_ASSERT(scope->lookup_class_symbol(classDeclaration->get_name()) != NULL);

     return classDeclaration;
   }
Ejemplo n.º 2
0
SgClassDeclaration* TestCodeBuilder::buildModelStruct()
{
    model_decl_ = buildStructDeclaration("model");
    SgClassDefinition* def = buildClassDefinition(model_decl_);

    pushScopeStack(isSgScopeStatement(def));

    SgVariableDeclaration* int_var = buildVariableDeclaration(int_var_name_, buildIntType());
    SgVariableDeclaration* int_array_var = 
        buildVariableDeclaration(int_array_var_name_, buildArrayType(buildIntType(), buildIntVal(array_size_)));

    def->append_member(int_var);
    def->append_member(int_array_var);

    popScopeStack();

#if 0
    model_type_ = model_decl_->get_type();
    model_obj_ = buildInitializedName(model_obj_name_, buildPointerType(model_type_));
    // Build the int var.
    int_var_ = buildBinaryExpression<SgArrowExp>(
            buildVarRefExp(model_obj_name_),
            buildVarRefExp(int_var_name_)); 
    int_var_->set_lvalue(true);

    // Build the int array var
    int_array_var_ = buildBinaryExpression<SgArrowExp>(
            buildVarRefExp(model_obj_name_),
            buildVarRefExp(int_array_var_name_));
#endif
    return model_decl_;
}
Ejemplo n.º 3
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameUnionFieldNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

// SgNode *sageReturnNode = NULL;

  SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode);

  if (sageClassDefinition != NULL)
    {
      ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL);
      if (sageClassDefinition->get_declaration ()->get_class_type () ==
          SgClassDeclaration::e_struct)
        {
          SgDeclarationStatementPtrList declarationStatementPtrList =
            sageClassDefinition->get_members ();

        typedef SgDeclarationStatementPtrList::iterator LI;

        for (LI i = declarationStatementPtrList.begin ();
             i != declarationStatementPtrList.end (); ++i)
          {
            SgNode *listElement = *i;

            SgVariableDeclaration *sageVariableDeclaration =
              isSgVariableDeclaration (listElement);

            if (sageVariableDeclaration != NULL)
              {


                typedef SgInitializedNamePtrList::iterator INITLI;

                SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables ();

                for (INITLI i = sageInitializedNameList.begin ();
                     i != sageInitializedNameList.end (); ++i)
                  {
                    SgInitializedName* initializedListElement = *i;
                    ROSE_ASSERT (isSgInitializedName (initializedListElement) != NULL);

                    returnNameList.push_back (initializedListElement->get_name().str());

                  }             /* End iteration over declarationStatementPtrList */

              }                 /* End iteration over declarationStatementPtrList */
          }

        }
    }

  return returnNameList;

}                               /* End function queryUnionFieldNames() */
Ejemplo n.º 4
0
SgMemberFunctionDeclaration*
get_default_constructor(SgClassDeclaration *c) {
    SgClassDefinition *d = c->get_definition();
    if (d != NULL) {
        SgDeclarationStatementPtrList::iterator i;
        for (i = d->get_members().begin(); i != d->get_members().end(); ++i) {
            if (SgMemberFunctionDeclaration* m=isSgMemberFunctionDeclaration(*i)) {
                if (m->get_name() == c->get_name() && m->get_args().empty())
                    return m;
            }
        }
    }
    return Ir::createMemberFunctionDeclaration(c->get_name());
}
SgDerivedTypeStatement *
RoseStatementsAndExpressionsBuilder::buildTypeDeclaration (
    std::string const & typeName, SgScopeStatement * scope)
{
  SgClassDefinition * classDefinition = new SgClassDefinition (
      RoseHelper::getFileInfo ());
  classDefinition->set_endOfConstruct (RoseHelper::getFileInfo ());
  classDefinition->setCaseInsensitive (true);

  SgDerivedTypeStatement* classDeclaration = new SgDerivedTypeStatement (
      RoseHelper::getFileInfo (), typeName, SgClassDeclaration::e_struct, NULL,
      classDefinition);
  classDeclaration->set_endOfConstruct (RoseHelper::getFileInfo ());
  classDeclaration->set_definingDeclaration (classDeclaration);
  classDeclaration->get_declarationModifier ().get_accessModifier ().setUndefined ();

  SgDerivedTypeStatement* nondefiningClassDeclaration =
      new SgDerivedTypeStatement (RoseHelper::getFileInfo (), typeName,
          SgClassDeclaration::e_struct, NULL, NULL);
  nondefiningClassDeclaration->set_endOfConstruct (RoseHelper::getFileInfo ());
  nondefiningClassDeclaration->set_parent (scope);
  nondefiningClassDeclaration->get_declarationModifier ().get_accessModifier ().setUndefined ();

  nondefiningClassDeclaration->set_type (SgClassType::createType (
      nondefiningClassDeclaration));
  classDeclaration->set_type (nondefiningClassDeclaration->get_type ());

  classDeclaration->set_firstNondefiningDeclaration (
      nondefiningClassDeclaration);

  nondefiningClassDeclaration->set_firstNondefiningDeclaration (
      nondefiningClassDeclaration);
  nondefiningClassDeclaration->set_definingDeclaration (classDeclaration);

  nondefiningClassDeclaration->setForward ();

  classDefinition->set_declaration (classDeclaration);
  classDefinition->get_declaration ()->get_declarationModifier ().get_accessModifier ().setUndefined ();

  classDeclaration->set_scope (scope);
  nondefiningClassDeclaration->set_scope (scope);

  classDeclaration->set_parent (scope);

  SgClassSymbol * classSymbol = new SgClassSymbol (nondefiningClassDeclaration);

  scope->insert_symbol (typeName, classSymbol);

  return classDeclaration;
}
Ejemplo n.º 6
0
void
FixupEnumValues::visit(SgNode* node)
   {
#if 0
     printf ("##### FixupEnumValues::visit(node = %p = %s) \n",node,node->sage_class_name());
#endif

     SgEnumVal* enumVal = isSgEnumVal(node);
     ROSE_ASSERT(enumVal != NULL);

     if (enumVal->get_declaration() == NULL)
        {
          ROSE_ASSERT(enumVal->get_startOfConstruct() != NULL);
          ROSE_ASSERT(enumVal->get_endOfConstruct() != NULL);

       // printf ("Found an enum value with a NULL declaration, fixup the declaration! \n");
       // enumVal->get_startOfConstruct()->display("Found an enum value with a NULL declaration");

          SgClassDefinition* enclosingClassDefinition = TransformationSupport::getClassDefinition(enumVal);
          ROSE_ASSERT(enclosingClassDefinition != NULL);

       // Now search for the enumVal name in the symbol table
          SgEnumFieldSymbol* enumFieldSymbol = enclosingClassDefinition->lookup_enum_field_symbol(enumVal->get_name());
          ROSE_ASSERT(enumFieldSymbol != NULL);
          if (enumFieldSymbol != NULL)
             {
            // We have now found the enum symbol in the scope of the class where the enum value was used.  
            // It could have been elsewhere and we don't search there, it could be in a namespace that was 
            // included using a using directive, so this could be very complex if it is not in the enclosing 
            // class.  To handle the case of where we can't find it, we ALLOW the declaration in the enumVal 
            // to be NULL, but we try to set it where we can easily figure it out.

                SgInitializedName* enumFieldName = enumFieldSymbol->get_declaration();
                SgNode* parentNode = enumFieldName->get_parent();
                ROSE_ASSERT(parentNode != NULL);
                SgEnumDeclaration* enumDeclaration = isSgEnumDeclaration(parentNode);
                ROSE_ASSERT(enumDeclaration != NULL);

             // Set the declaration to the enum declaration found!
             // printf ("Fixup the NULL declaration in enumVal = %p = %s with valid enum declaration = %p = %s \n",enumVal,enumVal->get_name().str(),enumDeclaration,enumDeclaration->get_name().str());
                enumVal->set_declaration(enumDeclaration);
             }


        }
   }
Ejemplo n.º 7
0
    bool findPublicVarMembers (SgNode *node, string &str) {
	SgVariableDeclaration *decl;
	if (decl = isSgVariableDeclaration(node)) {
	    SgDeclarationModifier &dfm = decl->get_declarationModifier();
	    if (dfm.get_accessModifier().isPublic()) {
		// check if it belongs to a class
		SgStatement *block = ((SgVariableDeclaration *) node)->get_scope();
		SgClassDefinition *classDef;
		if (classDef = isSgClassDefinition(block)) {
		    if (classDef->get_declaration()->get_class_type() == SgClassDeclaration::e_class) {
                        str = classDef->get_qualified_name().getString();		   
                        return true;
                    }
		}
	    } 
	}
	return false;
    }    
Ejemplo n.º 8
0
  NodeQuerySynthesizedAttributeType
NodeQuery::querySolverClassFields (SgNode * astNode)
{
  ROSE_ASSERT (astNode != 0);

  NodeQuerySynthesizedAttributeType returnNodeList;

  /*  cout << "The name of the node is: \" " << astNode->sage_class_name() << "\"\n";
      SgLocatedNode* sageLocatedNode = isSgLocatedNode(astNode);
      if(sageLocatedNode != NULL){
      cout << "The filename is: " << sageLocatedNode->getFileName() << " At line number :" << sageLocatedNode->get_file_info()->get_line() << "\n";
      } */
  // SgNode *sageReturnNode = NULL;

  SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode);

  if (sageClassDefinition != NULL)
  {
    ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL);
    if (sageClassDefinition->get_declaration ()->get_class_type () ==
        SgClassDeclaration::e_class)
    {
      SgDeclarationStatementPtrList declarationStatementPtrList =
        sageClassDefinition->get_members ();

      typedef SgDeclarationStatementPtrList::iterator LI;
      for (LI i = declarationStatementPtrList.begin ();
          i != declarationStatementPtrList.end (); ++i)
      {
        SgNode *listElement = *i;

        if (isSgVariableDeclaration (listElement) != NULL){
          /*    if(isSgVariableDeclaration(listElement)->get_name().str() != NULL)
                cout << "The name of the variable declaration is: \"" << isSgVariableDeclaration(listElement)->get_name().str() << "\"\n";
                else
                cout << "The name of the variable declaration is: \"\"\n";*/
          returnNodeList.push_back (listElement);
        }

      }
    }
  }
  return returnNodeList;
}                               /* End function querySolverClassFields() */
Ejemplo n.º 9
0
  NodeQuerySynthesizedAttributeType
NodeQuery::querySolverStructDefinitions (SgNode * astNode)
{
  ROSE_ASSERT (astNode != 0);
  SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode);
  NodeQuerySynthesizedAttributeType returnNodeList;

  if (sageClassDefinition != NULL)
  {
    SgClassDeclaration *sageClassDeclaration =
      isSgClassDeclaration (sageClassDefinition->get_parent ());
    ROSE_ASSERT (sageClassDeclaration != NULL);

    if (sageClassDeclaration->get_class_type () ==
        SgClassDeclaration::e_struct)
      returnNodeList.push_back (astNode);
  }

  return returnNodeList;
}                               /* End function querySolverClassFields() */
Ejemplo n.º 10
0
  NodeQuerySynthesizedAttributeType
NodeQuery::querySolverUnionFields (SgNode * astNode)
{


  ROSE_ASSERT (astNode != 0);

  NodeQuerySynthesizedAttributeType returnNodeList;

  // SgNode *sageReturnNode = NULL;

  SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode);

  if (sageClassDefinition != NULL)
  {
    ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL);
    if (sageClassDefinition->get_declaration ()->get_class_type () ==
        SgClassDeclaration::e_union)
    {
      SgDeclarationStatementPtrList declarationStatementPtrList =
        sageClassDefinition->get_members ();

      typedef SgDeclarationStatementPtrList::iterator LI;

      for (LI i = declarationStatementPtrList.begin ();
          i != declarationStatementPtrList.end (); ++i)
      {
        SgNode *listElement = *i;

        if (isSgVariableDeclaration (listElement) != NULL)
          returnNodeList.push_back (listElement);

      }

    }
  }


  return returnNodeList;

}                               /* End function querySolverUnionFields() */
Ejemplo n.º 11
0
void
Unparse_Java::unparseEnumType(SgEnumType* type, SgUnparse_Info& info)
   {
     SgEnumType* enum_type = isSgEnumType(type);
     ROSE_ASSERT(enum_type);

     if (info.isTypeSecondPart() == false)
        {
          SgEnumDeclaration *edecl = isSgEnumDeclaration(enum_type->get_declaration());
          SgClassDefinition *cdefn = NULL;
          SgNamespaceDefinitionStatement* namespaceDefn = NULL;

          ROSE_ASSERT(edecl != NULL);

       // Build reference to any possible enclosing scope represented by a SgClassDefinition or SgNamespaceDefinition
       // to be used check if name qualification is required.
          unp->u_exprStmt->initializeDeclarationsFromParent ( edecl, cdefn, namespaceDefn );

          if (info.isTypeFirstPart() == true && info.SkipEnumDefinition() == false)
             {
               unp->u_exprStmt->unparseAttachedPreprocessingInfo(edecl, info, PreprocessingInfo::before);
             }

          curprint ( "enum ");

          SgNamedType *ptype = NULL;
          if (cdefn != NULL)
             {
               ptype = isSgNamedType(cdefn->get_declaration()->get_type());
             }

          if (SageInterface::is_C_language() == true || SageInterface::is_C99_language() == true)
             {
               curprint ( enum_type->get_name().getString() + " ");
             }
            else
             {
            // DQ (7/20/2011): Test compilation without the generateNameQualifier() functions.
            // The C++ support is more complex and can require qualified names!
            // SgName nameQualifier = unp->u_name->generateNameQualifier( edecl , info );
               SgName nameQualifier;

            // printf ("nameQualifier (from unp->u_name->generateNameQualifier function) = %s \n",nameQualifier.str());
            // curprint ( "\n/* nameQualifier (from unp->u_name->generateNameQualifier function) = " + nameQualifier + " */ \n ";
               curprint ( nameQualifier.str());
               SgName nm = enum_type->get_name();

               if (nm.getString() != "")
                  {
                 // printf ("Output qualifier of current types to the name = %s \n",nm.str());
                    curprint ( nm.getString() + " ");
                  }
             }
        }

     if (info.isTypeFirstPart() == true)
        {
      // info.display("info before constructing ninfo");
         SgUnparse_Info ninfo(info);

      // don't skip the semicolon in the output of the statement in the class definition
         ninfo.unset_SkipSemiColon();

         ninfo.set_isUnsetAccess();

      // printf ("info.SkipEnumDefinition() = %s \n",(info.SkipEnumDefinition() == true) ? "true" : "false");

         if ( info.SkipEnumDefinition() == false)
            {
              SgUnparse_Info ninfo(info);
              ninfo.set_inEnumDecl();
              SgInitializer *tmp_init = NULL;
              SgName tmp_name;

              SgEnumDeclaration *enum_stmt = isSgEnumDeclaration(enum_type->get_declaration());
              ROSE_ASSERT(enum_stmt != NULL);

           // This permits support of the empty enum case! "enum x{};"
              curprint ( "{");

              SgInitializedNamePtrList::iterator p = enum_stmt->get_enumerators().begin();
              if (p != enum_stmt->get_enumerators().end())
                 {
                // curprint ( "{";
                   while (1)
                      {
                        unp->u_exprStmt->unparseAttachedPreprocessingInfo(*p, info, PreprocessingInfo::before);
                        tmp_name=(*p)->get_name();
                        tmp_init=(*p)->get_initializer();
                        curprint ( tmp_name.str());
                        if(tmp_init)
                           {
                             curprint ( "=");
                             unp->u_exprStmt->unparseExpression(tmp_init, ninfo);
                           }
                        p++;
                        if (p != enum_stmt->get_enumerators().end())
                           {
                             curprint ( ",");
                           }
                          else
                             break;
                       }
                 // curprint ( "}";
                  }

            // Putting the "inside" info right here is just a wild guess as to where it might really belong.
               unp->u_exprStmt->unparseAttachedPreprocessingInfo(enum_stmt, info, PreprocessingInfo::inside);

               curprint ( "}");

               unp->u_exprStmt->unparseAttachedPreprocessingInfo(enum_stmt, info, PreprocessingInfo::after);
             }
        }
   }
Ejemplo n.º 12
0
NodeQuerySynthesizedAttributeType NodeQuery::queryNodeClassDeclarationsFromTypeName(SgNode* node, SgNode* nameNode)
{
  NodeQuerySynthesizedAttributeType returnList;
  ROSE_ASSERT( nameNode != NULL );
  ROSE_ASSERT( node     != NULL );

  // finds the name which should be matched to 
  SgName* sageName = isSgName(nameNode);
  ROSE_ASSERT( sageName != NULL );
  std::string nameToMatch = sageName->str();
  ROSE_ASSERT( nameToMatch.length() > 0 );

  SgClassDeclaration *sageClassDeclaration = isSgClassDeclaration (node);

  if (sageClassDeclaration != NULL)
  {
    if(TransformationSupport::getTypeName(sageClassDeclaration->get_type()) == nameToMatch)
      returnList.push_back(node);
    else
    {
      SgClassDefinition* classDefinition = isSgClassDefinition(sageClassDeclaration->get_definition());
      ROSE_ASSERT( classDefinition != NULL );

      // SgBaseClassList baseClassList = classDefinition->get_inheritances();
      SgBaseClassPtrList baseClassList = classDefinition->get_inheritances();

      typedef SgBaseClassPtrList::iterator SgBaseClassPtrListIterator;
      for( SgBaseClassPtrListIterator baseClassElm = baseClassList.begin();
          baseClassElm != baseClassList.end(); ++baseClassElm)
      {
        // SgBaseClass baseClass = *baseClassElm;
        SgBaseClass* baseClass = *baseClassElm;
        // sageClassDeclaration = baseClass.get_base_class();
        sageClassDeclaration = baseClass->get_base_class();
        std::string typeName  = TransformationSupport::getTypeName ( sageClassDeclaration->get_type() );
        if( typeName == nameToMatch )
          returnList.push_back(node);
      }
    }

    /*
       SgType* typeNode = sageClassDeclaration->get_type ();
       ROSE_ASSERT (typeNode != NULL);

       string currentTypeName  = "";
       string previousTypeName = ""; 

       do{
       previousTypeName = currentTypeName;
       currentTypeName  = TransformationSupport::getTypeName (typeNode);

       typeNode = typeNode->findBaseType();
       ROSE_ASSERT( typeNode != NULL );

       if( currentTypeName == nameToMatch ){
       returnList.push_back(node);
       break;
       }
       cout<< "\n\n The typenames is : " << currentTypeName << "\n\n" << previousTypeName << "\n\n";

       }while( previousTypeName != currentTypeName);
     */ 
  }

  return returnList;
} /* End function:queryNodeCLassDeclarationFromName() */
Ejemplo n.º 13
0
StructLayoutInfo NonpackedTypeLayoutGenerator::layoutType(SgType* t) const {
  switch (t->variantT()) {
    case V_SgClassType: { // Also covers structs and unions
      SgClassDeclaration* decl = isSgClassDeclaration(isSgClassType(t)->get_declaration());
      ROSE_ASSERT (decl);
      decl = isSgClassDeclaration(decl->get_definingDeclaration());
      ROSE_ASSERT (decl);
      SgClassDefinition* def = decl->get_definition();
      ROSE_ASSERT (def);
      StructLayoutInfo layout;
      size_t currentOffset = 0;
      const SgBaseClassPtrList& bases = def->get_inheritances();
      for (SgBaseClassPtrList::const_iterator i = bases.begin();
           i != bases.end(); ++i) {
        SgBaseClass* base = *i;
        SgClassDeclaration* basecls = base->get_base_class();
        layoutOneField(basecls->get_type(), base, false, currentOffset, layout);
      }
      const SgDeclarationStatementPtrList& body = def->get_members();
      bool isUnion = (decl->get_class_type() == SgClassDeclaration::e_union);
      for (SgDeclarationStatementPtrList::const_iterator i = body.begin();
           i != body.end(); ++i) {
        SgDeclarationStatement* mem = *i;
        SgVariableDeclaration* vardecl = isSgVariableDeclaration(mem);
        SgClassDeclaration* classdecl = isSgClassDeclaration(mem);
        bool isUnnamedUnion = classdecl ? classdecl->get_isUnNamed() : false;
        if (vardecl) {
          if (!vardecl->get_declarationModifier().isDefault()) continue; // Static fields and friends
          ROSE_ASSERT (!vardecl->get_bitfield());
          const SgInitializedNamePtrList& vars = isSgVariableDeclaration(mem)->get_variables();
          for (SgInitializedNamePtrList::const_iterator j = vars.begin();
               j != vars.end(); ++j) {
            SgInitializedName* var = *j;
            layoutOneField(var->get_type(), var, isUnion, currentOffset, layout);
          }
        } else if (isUnnamedUnion) {
          layoutOneField(classdecl->get_type(), classdecl, isUnion, currentOffset, layout);
        } // else continue;
      }
      if (layout.alignment != 0 && layout.size % layout.alignment != 0) {
        size_t paddingNeeded = layout.alignment - (layout.size % layout.alignment);
        if (!isUnion) {
          layout.fields.push_back(StructLayoutEntry(NULL, layout.size, paddingNeeded));
        }
        layout.size += paddingNeeded;
      }
      return layout;
    }
    case V_SgArrayType: {
      StructLayoutInfo layout = this->beginning->layoutType(isSgArrayType(t)->get_base_type());
      layout.fields.clear();
      SgExpression* numElements = isSgArrayType(t)->get_index();

      //Adjustment for UPC array like a[100*THREADS],treat it as a[100]
      // Liao, 8/7/2008
      if (isUpcArrayWithThreads(isSgArrayType(t)))
      {
        SgMultiplyOp* multiply = isSgMultiplyOp(isSgArrayType(t)->get_index());
        ROSE_ASSERT(multiply);

     // DQ (9/26/2011): Do constant folding if required.
     // SageInterface::constantFolding(multiply);

        numElements = multiply->get_lhs_operand();
      }  
      if (!isSgValueExp(numElements)) {
        cerr << "Error: trying to compute static size of an array with non-constant size" << endl;
        abort();
      }
      layout.size *= SageInterface::getIntegerConstantValue(isSgValueExp(numElements));
      return layout;
    }
    case V_SgTypeComplex: {
    //"Each complex type has the same representation and alignment requirements as 
    //an array type containing exactly two elements of the corresponding real type"
      StructLayoutInfo layout = this->beginning->layoutType(isSgTypeComplex(t)->get_base_type());
      layout.size *= 2;
      return layout;
    }
    case V_SgTypeImaginary: {
      StructLayoutInfo layout = this->beginning->layoutType(isSgTypeImaginary(t)->get_base_type());
      return layout;
    }

    default: return ChainableTypeLayoutGenerator::layoutType(t);
  }
}
Ejemplo n.º 14
0
void fixupEdgBugDuplicateVariablesInAST()
   {
  // DQ (3/11/2006): Introduce tracking of performance of ROSE.
     TimingPerformance timer1 ("Fixup known EDG bug where some variable declarations are dropped from the source sequence lists:");

     std::set<SgVariableDeclaration*> declarations_to_remove;

  // Loop over all variables added using the convert_field_use() function.
     std::set<SgVariableDeclaration*>::iterator i = nodesAddedWithinFieldUseSet.begin();
     while (i != nodesAddedWithinFieldUseSet.end())
        {
          SgVariableDeclaration* var_decl = *i;
          SgName name = var_decl->get_variables()[0]->get_name();

          SgClassDefinition* classDefinition = isSgClassDefinition(var_decl->get_parent());
          ROSE_ASSERT(classDefinition != NULL);

          std::vector<SgDeclarationStatement*> & members = classDefinition->get_members();

       // Loop over all data members in the class.
          std::vector<SgDeclarationStatement*>::iterator j = members.begin();
          while (j != members.end())
             {
               SgVariableDeclaration* possible_matching_variable_declaration = isSgVariableDeclaration(*j);
               if (possible_matching_variable_declaration != NULL && possible_matching_variable_declaration != var_decl)
                  {
                    if (possible_matching_variable_declaration->get_variables()[0]->get_name() == name)
                       {
#if 0
                         printf ("matching variable declaration found for name = %s \n",name.str());
#endif
                         declarations_to_remove.insert(var_decl);
                       }
                  }
 
               j++;
             }

          i++;
        }

  // Now remove all of the variable declarations that we detected to be duplicates.
     std::set<SgVariableDeclaration*>::iterator k = declarations_to_remove.begin();
     while (k != declarations_to_remove.end())
        {
          SgDeclarationStatement* var_decl = *k;

          SgClassDefinition* classDefinition = isSgClassDefinition(var_decl->get_parent());
          ROSE_ASSERT(classDefinition != NULL);

          std::vector<SgDeclarationStatement*> myvector;
          myvector.push_back(*k);

          std::vector<SgDeclarationStatement*> & members = classDefinition->get_members();

       // members.erase(*k);
       // members.erase(myvector.begin(),myvector.end());

       // This is the remove/erase idiom.
          members.erase(remove(members.begin(), members.end(), *k), members.end());

          k++;
        }

   }
Ejemplo n.º 15
0
void
CompassAnalyses::VariableNameEqualsDatabaseName::Traversal::
visit(SgNode* node)
   { 
     if( isSgAssignInitializer(node) != NULL )
          assignExp = node;
  
     if( isSgAssignOp(node) != NULL )
          assignExp = node; 

     SgFunctionCallExp* funcCall = isSgFunctionCallExp(node);

  // See if we have a dot expression or arrow expression which
  // accesses the desired member function in the class we are looking for.
     if ( funcCall != NULL  )
        {
          SgExpression* funcExp = funcCall->get_function();

          if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) )
             {
               SgBinaryOp*     binOp = isSgBinaryOp(funcExp);
               SgExpression*   rhsOp = binOp->get_rhs_operand();
            // SgExpression*   lhsOp = binOp->get_lhs_operand();
               if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp)  )
                  {
                 // std::cout << "c1\n" ;

                    SgMemberFunctionSymbol*      funcSymbol = funcRef->get_symbol();
                    ROSE_ASSERT(funcSymbol->get_declaration() != NULL);

                 // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C)
                 // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL);
                    if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL)
                       {
                         SgMemberFunctionDeclaration* funcDecl   = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration());
                         ROSE_ASSERT( funcDecl != NULL );

                         SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope());
                         SgClassDeclaration*          clDecl     = isSgClassDeclaration(clDef->get_declaration());  

                      // SgClassDeclaration*          clDecl     = funcDecl->get_associatedClassDeclaration();

                         ROSE_ASSERT( clDecl != NULL );
                         std::string className    = clDecl->get_name().getString();

                         ROSE_ASSERT(funcDecl != NULL);
                         std::string functionName = funcDecl->get_name().getString();
 
                      // If the class is the class we are looking for see if the member function
                      // access is to the member function we are interested in.
                      // std::cout << "className = " << className << std::endl;
                      // std::cout << "functionName = " << functionName << std::endl;

                         if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) )
                            {
                              SgExprListExp*         actualArgs    = funcCall->get_args();
                              SgExpressionPtrList&   actualExpArgs = actualArgs->get_expressions ();

                              ROSE_ASSERT(actualExpArgs.size() == 1);
                              Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal);

                              ROSE_ASSERT( nodeLst.size() > 0);
                              SgStringVal* actualArg = isSgStringVal(*nodeLst.begin());
                              ROSE_ASSERT(actualArg != NULL);

                              std::string  stringArg = actualArg->get_value();

                              std::cout << "arg:" << stringArg << std::endl;

                              std::string varName;

                           // SgInitializedName* initName = NULL; 
                              if ( SgAssignInitializer* assignInit =  isSgAssignInitializer(assignExp) )
                                 {
                                   SgInitializedName* initName = isSgInitializedName(assignInit->get_parent());
                                   ROSE_ASSERT(initName != NULL);
                                 
                                   varName = initName->get_name().getString();
                                 }
                                else
                                 {
                                   if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) )
                                      {
                                        SgExpression*     lhsOp  = assignOp->get_lhs_operand();
                                        SgVarRefExp*      varRef = isSgVarRefExp(lhsOp);
                                        ROSE_ASSERT(varRef!=NULL);
                                        SgVariableSymbol* varSymbol = varRef->get_symbol();
                                        ROSE_ASSERT(varSymbol != NULL);
                                        SgInitializedName* initName = varSymbol->get_declaration();
                                        varName = initName->get_name().getString();
                                      }
                                 }
 
                              if (varName != "")
                                 {
                                // we are only interested in the part of the argument after the last ":"
                                // Database scopes in ALE3D are separated by ":"

                                   size_t posCol = stringArg.find_last_of(':');
                                 
                                   if (posCol != std::string::npos)
                                        stringArg = stringArg.substr(posCol+1);

                                 //Find violations to the rule
                                   if ( stringArg != varName)
                                      {
                                        output->addOutput(new CheckerOutput(assignExp));
                                        std::cout << "violation" << varName << std::endl;
                                      }
                                     else 
                                      {
                                        std::cout << "non=violation" << varName << std::endl;
                                      }
                                 }
                            }
                       }
                  }
             } 
        }
   } // End of the visit function.
void
FixupAstSymbolTablesToSupportAliasedSymbols::visit ( SgNode* node )
   {
  // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST.
#if ALIAS_SYMBOL_DEBUGGING
     printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit() (preorder AST traversal) node = %p = %s \n",node,node->class_name().c_str());
#endif

#if 0
  // DQ (7/23/2011): New support for linking namespaces sharing the same name (mangled name).
  // std::map<SgName,std::vector<SgNamespaceDefinition*> > namespaceMap;
     SgNamespaceDefinitionStatement* namespaceDefinition = isSgNamespaceDefinitionStatement(node);
     if (namespaceDefinition != NULL)
        {
       // DQ (7/23/2011): Assemble namespaces with the same name into vectors defined in the map 
       // accessed using the name of the namespace as a key.

#error "DEAD CODE"

          SgName name = namespaceDefinition->get_namespaceDeclaration()->get_name();
#if ALIAS_SYMBOL_DEBUGGING
          printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: namespace definition found for name = %s #symbols = %d \n",name.str(),namespaceDefinition->get_symbol_table()->size());
#endif
       // It is important to use mangled names to define unique names when namespaces are nested.
          SgName mangledNamespaceName = namespaceDefinition->get_namespaceDeclaration()->get_mangled_name();
#if ALIAS_SYMBOL_DEBUGGING
          printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: namespace definition associated mangled name = %s \n",mangledNamespaceName.str());
#endif
       // DQ (7/23/2011): Fixup the name we use as a key in the map to relect that some namespaces don't have a name.
          if (name == "")
             {
            // Modify the mangled name to reflect the unnamed namespace...

#if ALIAS_SYMBOL_DEBUGGING
               printf ("Warning in FixupAstSymbolTablesToSupportAliasedSymbols::visit(): Unnamed namespaces shuld be mangled to reflect the lack of a name \n");
#endif
               mangledNamespaceName += "_unnamed_namespace";
             }

#if ALIAS_SYMBOL_DEBUGGING
          printf ("namespace definition associated mangled name = %s \n",mangledNamespaceName.str());
#endif
#if ALIAS_SYMBOL_DEBUGGING
          printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: associated mangled name = %s namespaceMap size = %" PRIuPTR " \n",mangledNamespaceName.str(),namespaceMap.size());
#endif
          std::map<SgName,std::vector<SgNamespaceDefinitionStatement*> >::iterator i = namespaceMap.find(mangledNamespaceName);
          if (i != namespaceMap.end())
             {
               std::vector<SgNamespaceDefinitionStatement*> & namespaceVector = i->second;
#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: (found an entry): Namespace vector size = %" PRIuPTR " \n",namespaceVector.size());
#endif
            // Testing each entry...
               for (size_t j = 0; j < namespaceVector.size(); j++)
                  {
                    ROSE_ASSERT(namespaceVector[j] != NULL);
                    SgName existingNamespaceName = namespaceVector[j]->get_namespaceDeclaration()->get_name();
#if ALIAS_SYMBOL_DEBUGGING
                    printf ("Existing namespace (SgNamespaceDefinitionStatement) %p = %s \n",namespaceVector[j],existingNamespaceName.str());
#endif
                    if (j > 0)
                       {
                         ROSE_ASSERT(namespaceVector[j]->get_previousNamespaceDefinition() != NULL);
                       }

                    if (namespaceVector.size() > 1 && j < namespaceVector.size() - 2)
                       {
                         ROSE_ASSERT(namespaceVector[j]->get_nextNamespaceDefinition() != NULL);
                       }
                  }

#error "DEAD CODE"

               size_t namespaceListSize = namespaceVector.size();
               if (namespaceListSize > 0)
                  {
                    size_t lastNamespaceIndex = namespaceListSize - 1;

                 // DQ (5/9/2013): Before setting these, I think they should be unset (to NULL values).
                 // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL);
                 // ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL);
                 // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL);

                 // namespaceVector[lastNamespaceIndex]->set_nextNamespaceDefinition(namespaceDefinition);
#if 1
                    printf ("namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() = %p \n",namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition());
#endif
                    if (namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL)
                       {
                         namespaceVector[lastNamespaceIndex]->set_nextNamespaceDefinition(namespaceDefinition);
                       }
                      else
                       {
                      // DQ (5/9/2013): If this is already set then make sure it was set to the correct value.
                         ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == namespaceDefinition);
                       }

#error "DEAD CODE"

                 // DQ (5/9/2013): If this is already set then make sure it was set to the correct value.
                 // namespaceDefinition->set_previousNamespaceDefinition(namespaceVector[lastNamespaceIndex]);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == namespaceVector[lastNamespaceIndex]);

                 // DQ (5/9/2013): I think I can assert this.
                    ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_namespaceDeclaration()->get_name() == namespaceDefinition->get_namespaceDeclaration()->get_name());
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL);
#if 1
                    printf ("namespaceDefinition = %p namespaceDefinition->get_nextNamespaceDefinition() = %p \n",namespaceDefinition,namespaceDefinition->get_nextNamespaceDefinition());
#endif
                 // ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition()     == NULL);
                 // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL);
                  }

            // Add the namespace matching a previous name to the list.
               namespaceVector.push_back(namespaceDefinition);

#error "DEAD CODE"

            // Setup scopes as sources and distinations of alias symbols.
               SgNamespaceDefinitionStatement* referencedScope = namespaceDefinition->get_previousNamespaceDefinition();
               ROSE_ASSERT(referencedScope != NULL);
               SgNamespaceDefinitionStatement* currentScope = namespaceDefinition;
               ROSE_ASSERT(currentScope != NULL);

#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: Suppress injection of symbols from one namespace to the other for each reintrant namespace \n");
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: referencedScope #symbols = %d currentScope #symbols = %d \n",referencedScope->get_symbol_table()->size(),currentScope->get_symbol_table()->size());
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: referencedScope = %p currentScope = %p \n",referencedScope,currentScope);
#endif
#if 1
            // Generate the alias symbols from the referencedScope and inject into the currentScope.
               injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,currentScope,SgAccessModifier::e_default);
#endif
             }
            else
             {
#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: (entry NOT found): Insert namespace %p for name = %s into the namespaceMap \n",namespaceDefinition,mangledNamespaceName.str());
#endif
               std::vector<SgNamespaceDefinitionStatement*> list(1);
               ROSE_ASSERT(list.size() == 1);

#error "DEAD CODE"

               list[0] = namespaceDefinition;
#if 0
            // DQ (3/11/2012): New code, but maybe we should instead put the implicit "std" namespace into the global scope more directly.
               if (mangledNamespaceName == "std" && false)
                  {
                 // This case has to be handled special since the implicit "std" namespace primary declaration was 
                 // constructed but not added to the global scope.  But maybe it should be.
                  }
                 else
                  {
                 // DQ (7/24/2011): get_nextNamespaceDefinition() == NULL is false in the case of the AST copy tests 
                 // (see tests/nonsmoke/functional/CompileTests/copyAST_tests/copytest2007_30.C). Only  get_nextNamespaceDefinition() 
                 // appears to sometimes be non-null, so we reset them both to NULL just to make sure.
                    namespaceDefinition->set_nextNamespaceDefinition(NULL);
                    namespaceDefinition->set_previousNamespaceDefinition(NULL);

                    ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition()     == NULL);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL);
                  }
#else
            // DQ (7/24/2011): get_nextNamespaceDefinition() == NULL is false in the case of the AST copy tests 
            // (see tests/nonsmoke/functional/CompileTests/copyAST_tests/copytest2007_30.C). Only  get_nextNamespaceDefinition() 
            // appears to sometimes be non-null, so we reset them both to NULL just to make sure.
               namespaceDefinition->set_nextNamespaceDefinition(NULL);
               namespaceDefinition->set_previousNamespaceDefinition(NULL);

               ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition()     == NULL);
               ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL);
#endif
               namespaceMap.insert(std::pair<SgName,std::vector<SgNamespaceDefinitionStatement*> >(mangledNamespaceName,list));

#error "DEAD CODE"

#if ALIAS_SYMBOL_DEBUGGING
               printf ("namespaceMap.size() = %" PRIuPTR " \n",namespaceMap.size());
#endif
             }
        }

#error "DEAD CODE"

#else
  // DQ (5/23/2013): Commented out since we now have a newer and better namespace support for symbol handling.
  // printf ("NOTE:: COMMENTED OUT old support for namespace declarations in FixupAstSymbolTablesToSupportAliasedSymbols traversal \n");
#endif

     SgUseStatement* useDeclaration = isSgUseStatement(node);
     if (useDeclaration != NULL)
        {
       // This must be done in the Fortran AST construction since aliased symbols must be inserted
       // before they are looked up as part of name resolution of variable, functions, and types.
       // For C++ we can be more flexible and support the construction of symbol aliases within 
       // post-processing.
        }

  // DQ (4/14/2010): Added this C++ specific support.
  // In the future we may want to support the injection of alias symbols for C++ "using" directives and "using" declarations.
     SgUsingDeclarationStatement* usingDeclarationStatement = isSgUsingDeclarationStatement(node);
     if (usingDeclarationStatement != NULL)
        {
#if ALIAS_SYMBOL_DEBUGGING
          printf ("Found the SgUsingDeclarationStatement \n");
#endif
          SgScopeStatement* currentScope = usingDeclarationStatement->get_scope();
          ROSE_ASSERT(currentScope != NULL);

          SgDeclarationStatement* declaration     = usingDeclarationStatement->get_declaration();
          SgInitializedName*      initializedName = usingDeclarationStatement->get_initializedName();

       // Only one of these can be non-null.
          ROSE_ASSERT(initializedName != NULL || declaration != NULL);
          ROSE_ASSERT( (initializedName != NULL && declaration != NULL) == false);

          if (declaration != NULL)
             {
#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): declaration = %p = %s \n",declaration,declaration->class_name().c_str());
#endif
             }
            else
             {
               if (initializedName != NULL)
                  {
#if ALIAS_SYMBOL_DEBUGGING
                    printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): initializedName = %s \n",initializedName->get_name().str());
#endif
                  }
                 else
                  {
                    printf ("Error: both declaration and initializedName in SgUsingDeclarationStatement are NULL \n");
                    ROSE_ASSERT(false);
                  }
             }

#if 0
          printf ("Exiting at the base of FixupAstSymbolTablesToSupportAliasedSymbols::visit() \n");
          ROSE_ASSERT(false);
#endif
        }

     SgUsingDirectiveStatement* usingDirectiveStatement = isSgUsingDirectiveStatement(node);
     if (usingDirectiveStatement != NULL)
        {
#if ALIAS_SYMBOL_DEBUGGING
          printf ("Found the SgUsingDirectiveStatement \n");
#endif
          SgNamespaceDeclarationStatement* namespaceDeclaration = usingDirectiveStatement->get_namespaceDeclaration();
          ROSE_ASSERT(namespaceDeclaration != NULL);

          SgScopeStatement* currentScope    = usingDirectiveStatement->get_scope();

       // To be more specific this is really a SgNamespaceDefinitionStatement
          SgScopeStatement* referencedScope = namespaceDeclaration->get_definition();

          if (referencedScope == NULL)
             {
            // DQ (5/21/2010): Handle case of using "std" (predefined namespace in C++), but it not having been explicitly defined (see test2005_57.C).
               if (namespaceDeclaration->get_name() != "std")
                  {
                    printf ("ERROR: namespaceDeclaration has no valid definition \n");
                    namespaceDeclaration->get_startOfConstruct()->display("ERROR: namespaceDeclaration has no valid definition");

                 // DQ (5/20/2010): Added assertion to trap this case.
                    printf ("Exiting because referencedScope could not be identified.\n");
                    ROSE_ASSERT(false);
                  }
             }

       // Note that "std", as a predefined namespace, can have a null definition, so we can't 
       // insist that we inject all symbols in namespaces that we can't see explicitly.
          if (referencedScope != NULL)
             {
               ROSE_ASSERT(referencedScope != NULL);
               ROSE_ASSERT(currentScope != NULL);
#if 0
               printf ("Calling injectSymbolsFromReferencedScopeIntoCurrentScope() for usingDirectiveStatement = %p = %s \n",node,node->class_name().c_str());
#endif
               injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,currentScope,usingDirectiveStatement,SgAccessModifier::e_default);
             }

#if 0
          printf ("Exiting at the base of FixupAstSymbolTablesToSupportAliasedSymbols::visit() \n");
          ROSE_ASSERT(false);
#endif
        }

  // DQ (5/6/2011): Added support to build SgAliasSymbols in derived class scopes that reference the symbols of the base classes associated with protected and public declarations.
     SgClassDefinition* classDefinition = isSgClassDefinition(node);
     if (classDefinition != NULL)
        {
       // Handle any derived classes.
          SgBaseClassPtrList & baseClassList = classDefinition->get_inheritances();
          SgBaseClassPtrList::iterator i = baseClassList.begin();
          for ( ; i != baseClassList.end(); ++i)
             {
            // Check each base class.
               SgBaseClass* baseClass = *i;
               ROSE_ASSERT(baseClass != NULL);

               /* skip processing for SgExpBaseClasses (which don't have to define p_base_class) */
               if (baseClass->variantT() == V_SgExpBaseClass) {
                   continue;
               }

            // printf ("baseClass->get_baseClassModifier().displayString()                      = %s \n",baseClass->get_baseClassModifier().displayString().c_str());
            // printf ("baseClass->get_baseClassModifier().get_accessModifier().displayString() = %s \n",baseClass->get_baseClassModifier().get_accessModifier().displayString().c_str());

            // if (baseClass->get_modifier() == SgBaseClass::e_virtual)
               if (baseClass->get_baseClassModifier().get_modifier() == SgBaseClassModifier::e_virtual)
                  {
                 // Not clear if virtual as a modifier effects the handling of alias symbols.
                 // printf ("Not clear if virtual as a modifier effects the handling of alias symbols. \n");
                  }

            // DQ (6/22/2011): Define the access level for alias symbol's declarations to be included.
               SgAccessModifier::access_modifier_enum accessLevel = baseClass->get_baseClassModifier().get_accessModifier().get_modifier();

               SgClassDeclaration* tmpClassDeclaration    = baseClass->get_base_class();
               ROSE_ASSERT(tmpClassDeclaration != NULL);
#if 0
            // ROSE_ASSERT(tmpClassDeclaration->get_definingDeclaration() != NULL);
               SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(tmpClassDeclaration->get_definingDeclaration());
               ROSE_ASSERT(targetClassDeclaration != NULL);
               SgScopeStatement*   referencedScope  = targetClassDeclaration->get_definition();
            // We need this function to restrict it's injection of symbol to just those that are associated with public and protected declarations.
               injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,classDefinition,accessLevel);
#else
            // DQ (2/25/2012) We only want to inject the symbol where we have identified the defining scope.
               if (tmpClassDeclaration->get_definingDeclaration() != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(tmpClassDeclaration->get_definingDeclaration());
                    ROSE_ASSERT(targetClassDeclaration != NULL);
                    SgScopeStatement*   referencedScope  = targetClassDeclaration->get_definition();
#if 0
                    printf ("Calling injectSymbolsFromReferencedScopeIntoCurrentScope() for classDefinition = %p = %s baseClass = %p accessLevel = %d \n",
                         node,node->class_name().c_str(),baseClass,accessLevel);
#endif
                 // DQ (7/12/2014): Use the SgBaseClass as the causal node that has triggered the insertion of the SgAliasSymbols.
                 // We need this function to restrict it's injection of symbol to just those that are associated with public and protected declarations.
                    injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,classDefinition,baseClass,accessLevel);
                  }
                 else
                  {
                 // DQ (2/25/2012): Print a warning message when this happens (so far only test2012_08.C).
                    if (SgProject::get_verbose() > 0)
                       {
                         mprintf ("WARNING: In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): Not really clear how to handle this case where tmpClassDeclaration->get_definingDeclaration() == NULL! \n");
                       }
                  }
#endif
             }
        }


     SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(node);
     if (functionDeclaration != NULL)
        {
#if ALIAS_SYMBOL_DEBUGGING
          printf ("Found a the SgFunctionDeclaration \n");
#endif
       // SgScopeStatement*  functionScope   = functionDeclaration->get_scope();
          SgScopeStatement*  currentScope    = isSgScopeStatement(functionDeclaration->get_parent());
          SgClassDefinition* classDefinition = isSgClassDefinition(currentScope);

          if (classDefinition != NULL)
             {
            // This is a function declared in a class definition, test of friend (forget why it is important to test for isOperator().
               if (functionDeclaration->get_declarationModifier().isFriend() == true || functionDeclaration->get_specialFunctionModifier().isOperator() == true)
                  {
                 // printf ("Process all friend function with a SgAliasSymbol to where they are declared in another scope (usually global scope) \n");
#if 0
                    SgName name = functionDeclaration->get_name();

                    SgSymbol* symbol = functionDeclaration->search_for_symbol_from_symbol_table();
                    ROSE_ASSERT ( symbol != NULL );

                    SgAliasSymbol* aliasSymbol = new SgAliasSymbol (symbol);

                 // Use the current name and the alias to the symbol
                    currentScope->insert_symbol(name,aliasSymbol);
#endif
#if 0
                    printf ("Error: friend functions not processed yet! \n");
                    ROSE_ASSERT(false);
#endif
                  }
             }
        }

#if ALIAS_SYMBOL_DEBUGGING
     printf ("Leaving FixupAstSymbolTablesToSupportAliasedSymbols::visit() (preorder AST traversal) node = %p = %s \n",node,node->class_name().c_str());
#endif
   }
Ejemplo n.º 17
0
SgClassDeclaration*
buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope)
   {
  // This function builds a class declaration and definition 
  // (both the defining and nondefining declarations as required).

  // This is the class definition (the fileInfo is the position of the opening brace)
     SgClassDefinition* classDefinition   = new SgClassDefinition(SOURCE_POSITION);
     assert(classDefinition != NULL);

  // Set the end of construct explictly (where not a transformation this is the location of the closing brace)
     classDefinition->set_endOfConstruct(SOURCE_POSITION);

  // This is the defining declaration for the class (with a reference to the class definition)
     SgClassDeclaration* classDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition);
     assert(classDeclaration != NULL);
     classDeclaration->set_endOfConstruct(SOURCE_POSITION);

  // Set the defining declaration in the defining declaration!
     classDeclaration->set_definingDeclaration(classDeclaration);

  // Set the non defining declaration in the defining declaration (both are required)
     SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL);
     assert(classDeclaration != NULL);
     nondefiningClassDeclaration->set_endOfConstruct(SOURCE_POSITION);
     nondefiningClassDeclaration->set_scope(scope); // scope is needed for createType()
     nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration));

  // Set the internal reference to the non-defining declaration
     classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     classDeclaration->set_type (nondefiningClassDeclaration->get_type());

  // Set the defining and no-defining declarations in the non-defining class declaration!
     nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     nondefiningClassDeclaration->set_definingDeclaration(classDeclaration);

  // Set the nondefining declaration as a forward declaration!
     nondefiningClassDeclaration->setForward();

  // Liao (2/13/2008), symbol for the declaration
     SgClassSymbol* mysymbol = new SgClassSymbol(nondefiningClassDeclaration);
     scope->insert_symbol(name, mysymbol);

  // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)!
     classDefinition->set_declaration(classDeclaration);

  // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!)
     classDeclaration->set_scope(scope);

  //set parent
     classDeclaration->set_parent(scope);
     nondefiningClassDeclaration->set_parent(scope);

  // some error checking
     assert(classDeclaration->get_definingDeclaration() != NULL);
     assert(classDeclaration->get_firstNondefiningDeclaration() != NULL);
     assert(classDeclaration->get_definition() != NULL);

     ROSE_ASSERT(classDeclaration->get_definition()->get_parent() != NULL);

     return classDeclaration;
   }
Ejemplo n.º 18
0
//-----------------------------------------------------------------------------
// Functions required by the tree traversal mechanism
ClasshierarchyInhAttr
ClasshierarchyTraversal::evaluateInheritedAttribute (
                SgNode* astNode,
                ClasshierarchyInhAttr inheritedAttribute )
{
        GlobalDatabaseConnection *gdb;    // db connection
        //long funcId;                                                                                  // id of a function declaration
        Classhierarchy *classhier = getClasshierarchy();
        gdb = getDB();  

        switch(astNode->variantT())
        {

                case V_SgMemberFunctionDeclaration: {
                        SgMemberFunctionDeclaration *funcDec = isSgMemberFunctionDeclaration( astNode );
                        //funcDec = funcDef->get_declaration();
                        //if(isSgMemberFunctionDeclaration(funcDec)) {
                                // add to class hierarchy if member function definition
                                //if(isSgMemberFunctionDeclaration()) {
                                //cerr << " adding CHvinf for MembFunc " << endl;
                                SgClassDefinition *classDef = isSgClassDefinition( funcDec->get_scope() );
                                //assert(classDef);
                                if(classDef) {
                                        string classname = classDef->get_qualified_name().str();
                                        // get the classhier. vertex
                                        Classhierarchy::dbgVertex chVert = 0; //?? init necessary
                                        bool foundClass = false;
                                        Classhierarchy::dbgVertexIterator chvi,chvend;
                                        boost::tie(chvi,chvend) = boost::vertices( *getClasshierarchy() );
                                        for(; chvi!=chvend; chvi++) {
                                                if( boost::get( vertex_dbg_data,  *getClasshierarchy() , *chvi).get_typeName() == classname ) {
                                                        chVert = *chvi;
                                                        foundClass = true;
                                                }
                                        }
                                        if(foundClass) {
                                                property_map< Classhierarchy::dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *getClasshierarchy() );
                                                chMap[ chVert ].defined.insert( funcDec );
                                                //get type?
                                                //cerr << " added! "; // debug
                                        }
                                }

                        //}
                        cerr << " found V_SgMemberFunctionDeclaration done for " <<funcDec->get_mangled_name().str()<< " " << endl; // debug
                        } break;

                case V_SgClassDefinition: {
                        cerr << " found V_SgClassDef of "; // debug
                        SgClassDefinition *classDef = isSgClassDefinition( astNode );
                        assert( classDef );
                        SgName classname = classDef->get_qualified_name();

                        // make db entry
                        long typeId = UNKNOWNID;
                        typesTableAccess types( gdb );
                        typesRowdata newtype( typeId, getProjectId(), classname.str() );
                        typeId = types.retrieveCreateByColumn( &newtype, "typeName", newtype.get_typeName(), newtype.get_projectId() );
                        cerr << classname.str()<< ", id:" << newtype.get_id() << endl; // debug
                        //classhier->addNode( newtype, newtype.get_typeName() );
                        //classhier->insertWithName( newtype, newtype.get_typeName() );
                        classhier->insertVertex( newtype, newtype.get_typeName() );

                        SgBaseClassList inherits = classDef->get_inheritances();
                        for( SgBaseClassList::iterator i=inherits.begin(); i!=inherits.end(); i++) {
                                SgClassDeclaration *parentDecl = (*i).get_base_class();
                                cerr << " found inheritance from " ; // debug
                                assert( parentDecl );

                                // add new edge
                                typesRowdata partype( UNKNOWNID, getProjectId(), parentDecl->get_name().str() ); // MANGLE
                                long parentId = types.retrieveCreateByColumn( &partype, "typeName", partype.get_typeName(), partype.get_projectId() );
                                cerr << parentDecl->get_name().str() << ", id: " << parentId << endl;

                                // add to class hierarchy graph, allow only one edge per inheritance
                                //A classhier->addNode( partype, partype.get_typeName() );
                                //A classhier->addEdge( newtype, partype, false );
                                classhier->insertEdge( newtype, partype );
                        }
                        
                        } break;

        } // switch node type


        // Note that we have to use a particular constructor (to pass on context information about source code position).
        // This allows the Rewrite mechanism to position new source code relative to the current position using a simple interface.
        ClasshierarchyInhAttr returnAttribute(inheritedAttribute,astNode);
        // FIXME why not return inheritedAttribute???

        return returnAttribute;
}
Ejemplo n.º 19
0
//! search for all possible (virtual) function calls 
vector<SgMemberFunctionDeclaration*> 
Classhierarchy::searchMemberFunctionCalls(SgMemberFunctionDeclaration* mfCall)
{
        vector<SgMemberFunctionDeclaration*> retvec;
        property_map< dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *this );

        SgClassDefinition *classDef  = mfCall->get_scope();
        SgName                                           classname = classDef->get_qualified_name(); // MANGLE
        string                                           cnamestr  = classname.str();
        graph_traits< dbgType >::vertex_iterator vi,vend;
        dbgVertex vdesc = *vi;
        bool foundVertex = false;
        tie(vi,vend) = vertices( *this );
        for(; vi!=vend; vi++) {
                //cerr << " BCH v i"<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl;
                if( get(vertex_dbg_data, *this, *vi).get_typeName() == cnamestr ) {
                        //cerr << " SMF srch "<< cnamestr <<" vi "<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl;
                        vdesc = *vi;
                        foundVertex = true;
                        break;
                }
        }
        if(!foundVertex) { cerr << " SMF srch "<< cnamestr <<" vi "<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; }
        assert( foundVertex );

        set<dbgVertex> treeset;
        treeset.insert( vdesc );

        // first find "highest" class in CH that still provides this MF
        dbgVertex vhighest = vdesc; // first assume its the current one
        graph_traits<dbgType>::out_edge_iterator oi,oend;
        tie(oi,oend) = out_edges( vdesc, *this);
        for(; oi!=oend; oi++) {
                //cerr << " SMF inherits from "<< get(vertex_index,*this,target(*oi,*this))<< " i1" << get(vertex_index1, *this, target(*oi,*this))<<","<< get(vertex_name, *this, target(*oi,*this)) << endl;
                
                // does any of the base classes implement the member function?
                bool noParentImpl = true; 
                
                // check if this base class also implements MF
                for(set<SgNode*>::iterator chd= chMap[target(*oi,*this)].inherited.begin(); 
                                chd!= chMap[target(*oi,*this)].inherited.end(); chd++) {
                        SgFunctionDeclaration *inhFunc = isSgFunctionDeclaration( *chd );
                        bool virt = false;
                        //cerr << "  TOPO v srch1" << endl;
                        if(inhFunc->isVirtual()) virt = true;
                        if( (virt) && (compareFunctionDeclarations(inhFunc,mfCall)) ) {
                                // remeber for traversal
                                treeset.insert( target(*oi, *this) );
                                noParentImpl = false;
                        }
                }
                if(noParentImpl) {
                        // we found it
                        vhighest = target(*oi, *this);
                        break;
                }
        }
        //cerr << " SMF high "<< cnamestr <<" vi "<< get(vertex_index,*this,vhighest)<< " i1" << get(vertex_index1, *this, vhighest)<<","<< get(vertex_name, *this, vhighest) << endl; 

        // now traverse class hierachy downwards, for all children that implement this function, add to set
        set<dbgVertex> tovisit;
        set<dbgVertex> visited;
        tovisit.insert( vhighest );
        //hier weiter
        while( tovisit.size() > 0 ) {
                dbgVertex currVert = *(tovisit.begin());
                tovisit.erase( currVert );
                visited.insert( currVert );
        //cerr << " SMF visi "<< get(vertex_index,*this,currVert)<< " i1" << get(vertex_index1, *this, currVert)<<","<< get(vertex_name, *this, currVert) << endl; 
                for(set<SgNode*>::iterator chd= chMap[currVert].defined.begin(); chd!= chMap[currVert].defined.end(); chd++) {
                        SgMemberFunctionDeclaration*inhFunc = isSgMemberFunctionDeclaration( *chd );
                        if(compareFunctionDeclarations(inhFunc,mfCall)) {
                                retvec.push_back( inhFunc );
                        }
                }
                graph_traits<dbgType>::in_edge_iterator ii,iend;
                tie(ii,iend) = in_edges( currVert, *this);
                for(; ii!=iend; ii++) {
                        dbgVertex child = source(*ii, *this);
                        // only insert of not already visited
                        set<dbgVertex>::iterator found = visited.find( child );
                        if(found == visited.end()) 
                                tovisit.insert( child );
                }
        }

        //retvec.push_back( mfCall );
        return retvec;
}
int main(int argc, char **argv)
{
  SgProject *project = frontend(argc, argv);
  
  // Instantiate a class hierarchy wrapper.
  ClassHierarchyWrapper classHierarchy( project );

#if 0
  std::list<SgNode *> nodes2 = NodeQuery::querySubTree(project,
						      V_SgVariableDefinition);

  for (std::list<SgNode *>::iterator it = nodes2.begin();
       it != nodes2.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgVariableDefinition *varDefn =
      isSgVariableDefinition(n);
    ROSE_ASSERT(varDefn != NULL);

    std::cout << "Var defn: " << varDefn->unparseToCompleteString() << std::endl;

  }

  std::list<SgNode *> nodes1 = NodeQuery::querySubTree(project,
						      V_SgVariableDeclaration);

  for (std::list<SgNode *>::iterator it = nodes1.begin();
       it != nodes1.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgVariableDeclaration *varDecl =
      isSgVariableDeclaration(n);
    ROSE_ASSERT(varDecl != NULL);

    SgInitializedNamePtrList &variables =
      varDecl->get_variables();
    SgInitializedNamePtrList::iterator varIter;
    for (varIter = variables.begin(); 
	 varIter != variables.end(); ++varIter) {
      
      SgNode *var = *varIter;
      ROSE_ASSERT(var != NULL);
      
      SgInitializedName *initName =
	isSgInitializedName(var);
      ROSE_ASSERT(initName != NULL);
      
      if ( isSgClassType(initName->get_type()) ) {

	SgClassType *classType = isSgClassType(initName->get_type());
	ROSE_ASSERT(classType != NULL);

	SgDeclarationStatement *declStmt = classType->get_declaration();
	ROSE_ASSERT(declStmt != NULL);
	
	SgClassDeclaration *classDeclaration = isSgClassDeclaration(declStmt);
	ROSE_ASSERT(classDeclaration != NULL);
      
	//	std::cout << "From var decl got: " << classDeclaration->unparseToCompleteString() << std::endl;

	SgClassDefinition *classDefinition =
	  classDeclaration->get_definition();
	if ( classDefinition != NULL ) {
	  std::cout << "From var decl got: " << classDefinition->unparseToCompleteString() << std::endl;
	}

      }

    }
    

  }

  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgClassDeclaration);

  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgClassDeclaration *classDeclaration1 =
      isSgClassDeclaration(n);
    ROSE_ASSERT(classDeclaration1 != NULL);

    SgDeclarationStatement *definingDecl =
      classDeclaration1->get_definingDeclaration();
    if ( definingDecl == NULL )
      continue;
    
    SgClassDeclaration *classDeclaration =
      isSgClassDeclaration(definingDecl);
    ROSE_ASSERT(classDeclaration != NULL);


    SgClassDefinition *classDefinition =
      classDeclaration->get_definition();
    ROSE_ASSERT(classDefinition != NULL);

    std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl;

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

    // Iterate over all subclasses.
    for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	 subclassIt != subclasses.end(); ++subclassIt) {
      
      SgClassDefinition *subclass = *subclassIt;
      ROSE_ASSERT(subclass != NULL);
      
      std::cout << "subclass" << std::endl;

    }

  }
#endif
#if 1
#if 0
  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgClassDefinition);

  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgClassDefinition *classDefinition =
      isSgClassDefinition(n);
    ROSE_ASSERT(classDefinition != NULL);

    std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl;

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

    // Iterate over all subclasses.
    for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	 subclassIt != subclasses.end(); ++subclassIt) {
      
      SgClassDefinition *subclass = *subclassIt;
      ROSE_ASSERT(subclass != NULL);
      
      std::cout << "subclass" << std::endl;

    }

  }
#else
  // Collect all function/method invocations.
  std::list<SgNode *> nodes = NodeQuery::querySubTree(project,
						      V_SgFunctionCallExp);

  unsigned int numCallSites = 0;
  unsigned int numMonomorphicCallSites = 0;
  unsigned int numPossibleResolutions = 0;

  // Visit each call site.
  for (std::list<SgNode *>::iterator it = nodes.begin();
       it != nodes.end(); ++it ) {

    SgNode *n = *it;
    ROSE_ASSERT(n != NULL);

    SgFunctionCallExp *functionCallExp =
      isSgFunctionCallExp(n);
    ROSE_ASSERT(functionCallExp != NULL);

    // We are only interested in examining method invocations.
    bool isDotExp = false;
    bool isLhsRefOrPtr = false;

    //    std::cout << "method?: " << functionCallExp->unparseToCompleteString() << std::endl;

    if ( !isMethodCall(functionCallExp, isDotExp, isLhsRefOrPtr) )
      continue;
    
    //    std::cout << "method: " << functionCallExp->unparseToCompleteString() << std::endl;

    numCallSites++;

    if ( isDotExp && !isLhsRefOrPtr ) {
      // If this is a dot expression (i.e., a.foo()), we can
      // statically determine its type-- unless the left-hand
      // side is a reference type.
      numMonomorphicCallSites++;
      numPossibleResolutions++;
      //      std::cout << "dot: " << functionCallExp->unparseToCompleteString() << std::endl;
      continue;
    }

    //    std::cout << "methodPtr: " << functionCallExp->unparseToCompleteString() << std::endl;

    // Retrieve the static function declaration.
    SgFunctionDeclaration *functionDeclaration = 
      getFunctionDeclaration(functionCallExp);

    // Ensure it is actually a method declaration.
    SgMemberFunctionDeclaration *memberFunctionDeclaration =
      isSgMemberFunctionDeclaration(functionDeclaration);
    ROSE_ASSERT(memberFunctionDeclaration != NULL);

    unsigned int numResolutionsForMethod = 0;

    // Certainly can be resolved to the static method (unless it
    // is pure virtual).
    if ( !isPureVirtual(memberFunctionDeclaration) ) {
      numResolutionsForMethod++;
    }

#if 0
    if ( ( isVirtual(functionDeclaration) ) ||
	 ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) {
#else
      if ( isVirtual(functionDeclaration) ) {
#endif      
      //      std::cout << "tracking: " << functionDeclaration->unparseToString() << std::endl;

      SgClassDefinition *classDefinition = 
	isSgClassDefinition(memberFunctionDeclaration->get_scope());
      ROSE_ASSERT(classDefinition != NULL);
      
      SgClassDefinitionPtrList subclasses = 
	classHierarchy.getSubclasses(classDefinition);

      // Iterate over all subclasses.
      for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin();
	   subclassIt != subclasses.end(); ++subclassIt) {

	SgClassDefinition *subclass = *subclassIt;
	ROSE_ASSERT(subclass != NULL);

	//	std::cout << "subclass" << std::endl;

	// Iterate over all of the methods defined in this subclass.
	SgDeclarationStatementPtrList &decls =
	  subclass->get_members();
	for (SgDeclarationStatementPtrList::iterator declIter = decls.begin();
	     declIter != decls.end(); ++declIter) {

	  SgDeclarationStatement *declStmt = *declIter;
	  ROSE_ASSERT(declStmt != NULL);

	  SgMemberFunctionDeclaration *method =
	    isSgMemberFunctionDeclaration(declStmt);
	  if ( method == NULL ) {
	    continue;
	  }

	  //	  std::cout << "checking overrides" << std::endl;
	  // Determine whether subclass of the class defining this
	  // method overrides the method.
#if 1
	  if ( matchingFunctions(method,
				       memberFunctionDeclaration) ) {
	    //	    std::cout << "overries" << std::endl;
	    // Do not consider a pure virtual method to be an 
	    // overriding method (since it can not be invoked).
	    if ( !isPureVirtual(method) ) {
	      numResolutionsForMethod++;
	    }
	  }
#else
	  if ( methodOverridesVirtualMethod(method, 
					    memberFunctionDeclaration) ) {
	    //	    std::cout << "overries" << std::endl;
	    numResolutionsForMethod++;
	  }
#endif
	}

      }

      if ( numResolutionsForMethod <= 1 )
	numMonomorphicCallSites++;
      numPossibleResolutions += numResolutionsForMethod;

      if ( ( numResolutionsForMethod ) > 1 ) {
	std::cout << "Method invocation has " << numResolutionsForMethod << " possible resolutions " << std::endl;
	std::cout << functionCallExp->unparseToCompleteString() << std::endl;
      }
    }

  }
#endif
#endif
  return 0;
}
bool isDeclaredVirtualWithinClassAncestry(SgFunctionDeclaration *functionDeclaration, SgClassDefinition *classDefinition)
{
  SgType *functionType =
    functionDeclaration->get_type();
  ROSE_ASSERT(functionType != NULL);

  // Look in each of the class' parent classes.
  SgBaseClassPtrList & baseClassList = classDefinition->get_inheritances(); 
  for (SgBaseClassPtrList::iterator i = baseClassList.begin(); 
       i != baseClassList.end(); ++i) {
 
    SgBaseClass *baseClass = *i;
    ROSE_ASSERT(baseClass != NULL);

    SgClassDeclaration *classDeclaration = baseClass->get_base_class(); 
    ROSE_ASSERT(classDeclaration != NULL);

    SgDeclarationStatement *definingDecl =
      classDeclaration->get_definingDeclaration();
    if ( definingDecl == NULL )
      continue;
    
    SgClassDeclaration *definingClassDeclaration =
      isSgClassDeclaration(definingDecl);
    ROSE_ASSERT(classDeclaration != NULL);

    SgClassDefinition *parentClassDefinition =
      definingClassDeclaration->get_definition();

    if ( parentClassDefinition == NULL )
      continue;

    // Visit all methods in the parent class.
    SgDeclarationStatementPtrList &members = 
      parentClassDefinition->get_members(); 

    bool isDeclaredVirtual = false;

    for (SgDeclarationStatementPtrList::iterator it = members.begin(); 
	 it != members.end(); ++it) { 
    
      SgDeclarationStatement *declarationStatement = *it; 
      ROSE_ASSERT(declarationStatement != NULL);
      
      switch(declarationStatement->variantT()) {
      
      case V_SgMemberFunctionDeclaration:
	{
	  SgMemberFunctionDeclaration *memberFunctionDeclaration =  
	    isSgMemberFunctionDeclaration(declarationStatement); 

	  if ( isVirtual(memberFunctionDeclaration) ) {

	    SgType *parentMemberFunctionType =
	      memberFunctionDeclaration->get_type();
	    ROSE_ASSERT(parentMemberFunctionType != NULL);

	    if ( parentMemberFunctionType == functionType ) {
	      return true;
	    }

	  }
	  break;

	}
      default:
	{
	  break;
	}

      }

    }

    if ( isDeclaredVirtualWithinClassAncestry(functionDeclaration, 
					      parentClassDefinition) ) {
      return true;
    }

  }

  return false;
}
void
InsertFortranContainsStatement::visit ( SgNode* node )
   {
  // DQ (10/3/2008): This bug in OFP is now fixed so no fixup is required.
     printf ("Error: fixup of contains statement no longer required. \n");
     ROSE_ASSERT(false);

  // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST.
     ROSE_ASSERT(node != NULL);
#if 0
     Sg_File_Info* fileInfo = node->get_file_info();

     printf ("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

     SgFunctionDefinition* functionDefinition = isSgFunctionDefinition(node);

  // This is for handling where CONTAINS is required in a function
     if (functionDefinition != NULL)
        {
          SgBasicBlock* block = functionDefinition->get_body();
          SgStatementPtrList & statementList = block->get_statements();
          SgStatementPtrList::iterator i = statementList.begin();

          bool firstFunctionDeclaration = false;
          bool functionDeclarationSeen  = false;

          while (i != statementList.end() && firstFunctionDeclaration == false)
             {
               SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);

            // DQ (1/20/2008): Note that entry statements should not cause introduction of a contains statement!
               if (isSgEntryStatement(functionDeclaration) != NULL)
                    functionDeclaration = NULL;

               if (functionDeclaration != NULL)
                  {
                    firstFunctionDeclaration = functionDeclarationSeen == false;
                    functionDeclarationSeen  = true;

                    if (firstFunctionDeclaration == true)
                       {
                      // Insert a CONTAINS statement.
                      // printf ("Building a contains statement (in function) \n");
                         SgContainsStatement* containsStatement = new SgContainsStatement();
                         SageInterface::setSourcePosition(containsStatement);
                         containsStatement->set_definingDeclaration(containsStatement);

                         block->get_statements().insert(i,containsStatement);
                         containsStatement->set_parent(block);
                         ROSE_ASSERT(containsStatement->get_parent() != NULL);
                       }
                  }

               i++;
             }
        }

#if 0
  // OFP now has better support for the CONTAINS statement so this code is not longer required.

  // The use of CONTAINS in modules appears to be handled by OFP, so no fixup is required.
     SgClassDefinition* classDefinition = isSgClassDefinition(node);

  // This is for handling where CONTAINS is required in a module
     if (classDefinition != NULL)
        {
          SgDeclarationStatementPtrList & statementList = classDefinition->get_members();
          SgDeclarationStatementPtrList::iterator i = statementList.begin();

          bool firstFunctionDeclaration = false;
          bool functionDeclarationSeen  = false;

          while (i != statementList.end() && firstFunctionDeclaration == false)
             {
               printf ("InsertFortranContainsStatement: *i in statementList in module = %p = %s \n",*i,(*i)->class_name().c_str());

               SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i);
               if (functionDeclaration != NULL)
                  {
                    firstFunctionDeclaration = functionDeclarationSeen == false;
                    functionDeclarationSeen  = true;

                    if (firstFunctionDeclaration == true)
                       {
                      // Insert a CONTAINS statement.
                      // printf ("Building a contains statement (in module) \n");
                         SgContainsStatement* containsStatement = new SgContainsStatement();
                         SageInterface::setSourcePosition(containsStatement);
                         containsStatement->set_definingDeclaration(containsStatement);

                      // This insert function does not set the parent (unlike for SgBasicBlock)
                         classDefinition->get_members().insert(i,containsStatement);
                         containsStatement->set_parent(classDefinition);
                         ROSE_ASSERT(containsStatement->get_parent() != NULL);
                       }
                  }

               i++;
             }
        }
#endif
   }
Ejemplo n.º 23
0
string
SIDL_TreeTraversal::generateSIDLFunctionDeclaration(SgFunctionDeclaration* functionDeclarationStatement )
{
    ROSE_ASSERT (functionDeclarationStatement != NULL);
    ROSE_ASSERT (functionDeclarationStatement->get_file_info() != NULL);
    const SgSpecialFunctionModifier &functionModifier = functionDeclarationStatement->get_specialFunctionModifier();

    string functionName = functionDeclarationStatement->get_name().str();
    string sidlFunctionName ;
    if (functionModifier.isConstructor()) {
        if (functionDeclarationStatement->get_args().size() == 0) return ""; // skip empty constructor
        sidlFunctionName = constructorName;
    }
    else {
        sidlFunctionName = functionName;
    }

    // We have to force the mangled name to be generated before we access it (else we just get "defaultName")
    string mangledFunctionName = functionDeclarationStatement->get_mangled_name().str();

    sidlFunctionName = stringifyOperatorWithoutSymbols(sidlFunctionName);

    // Get the class name
    SgClassDefinition* classDefinition   = isSgClassDefinition(functionDeclarationStatement->get_scope());

    // DQ (1/7/2004): Modified for make EDG version 3.3 work (member function declarations's normalized by EDG)
    if (classDefinition != NULL)
    {
        SgClassDeclaration* classDeclaration = classDefinition->get_declaration();

        string className = classDeclaration->get_name().str();

        overloadInformation info = isOverloaded(classDefinition,functionName,mangledFunctionName);
        int orderofOverloadedFunction = info.get_order();

        // If function is overloaded then append the number indicating the order of appearance in the
        // class declaration
        if (info.get_count() > 1)
        {
            vector<SgType*> types = info.get_types();

            // SgInitializedNamePtrList &args = functionDeclarationStatement->get_args ();
            int size = types.size();
            if(size > 0)
            {
                if(size < 3)
                {
                    sidlFunctionName += "[";
                    for(vector<SgType*>::iterator i = types.begin(); i!= types.end(); i++)
                    {
                        if(i != types.begin()) sidlFunctionName += "_";
                        if(isSgPointerType(*i) != NULL)	sidlFunctionName += "P";
                        sidlFunctionName += sidlOverloadExtension(TransformationSupport::getTypeName(*i));
                    }
                    sidlFunctionName += "]";
                }
                else
                    sidlFunctionName += "["+numberToOverloadString(orderofOverloadedFunction)+"]";
            }
        }
    }
    else
    {
        printf ("EDG version 3.3 can return a null pointer to the member function definition \n");
    }

    SgFunctionType* functionType = functionDeclarationStatement->get_type();
    ROSE_ASSERT(functionType != NULL);

    // SgType* returnType = functionType->get_return_type();
    // ROSE_ASSERT (returnType != NULL);
    // string returnTypeName = TransformationSupport::getTypeName(returnType);

    // printf ("function has_ellipses %s \n",(functionType->get_has_ellipses() != false) ? "true" : "false");
    // showSgFunctionType(cout, functionType, "Called from generateSIDLFunctionDeclaration", 0 );
    // printf ("Function return type = %s \n",returnTypeName.c_str());

#if 0
    SgTypePtrList & argumentTypeList = functionType->get_arguments();
    ROSE_ASSERT (argumentTypeList.size() >= 0);
    SgTypePtrList::iterator argumentIterator = argumentTypeList.begin();

    for (argumentIterator = argumentTypeList.begin(); argumentIterator != argumentTypeList.end(); argumentIterator++)
    {
        // showSgType(os,(*argumentIterator), label, depth+1);

        string argumentTypeName = TransformationSupport::getTypeName(*argumentIterator);
        printf ("-----> argument #%d  argumentTypeName = %s \n",argumentCounter++,argumentTypeName.c_str());
    }
#endif

    //Determine the SIDL parameter passing mechanism (in,out,inout)
    SgInitializedNamePtrList & argumentList = functionDeclarationStatement->get_args();
    string parameterTypesAndNames;
    SgInitializedNamePtrList::iterator i;

    unsigned int argumentCounter = 0;
    for (i = argumentList.begin(); i != argumentList.end(); i++)
    {
        SgType* type = (*i)->get_type();
        ROSE_ASSERT (type != NULL);

        string typeName = TransformationSupport::getTypeName(type);
        ROSE_ASSERT (typeName.c_str() != NULL);

        string sidlParameterPassingMechanim = "in";

        //it seems like the has_ellipses value is wrong, so we'll set it
        functionType->set_has_ellipses(false);
        if(type->variantT() == V_SgTypeEllipse)
        {
            sidlParameterPassingMechanim = "inout";
            functionType->set_has_ellipses(true);
        }
        //else if (type->variantT() == V_SgTypeVoid)
        /*else if (rose::stringDuplicate(type->sage_class_name()) == "SgTypeVoid")
        {
        	printf("found a void\n");
        	//void type is only viable for a pointer.  foo(void) will just become foo()
        	if(isSgPointerType(type) != NULL)
        	{
        		printf("found a void pointer\n");
        		sidlParameterPassingMechanim ="inout opaque";
        	}
        }*/
        else if (isSgReferenceType(type) != NULL)
        {
            sidlParameterPassingMechanim = "inout";
        }
        else if (isSgPointerType(type) != NULL)
        {
            sidlParameterPassingMechanim = "inout";
        }
        else if (isSgArrayType(type) != NULL)
        {
            SgArrayType array = isSgArrayType(type);
            sidlParameterPassingMechanim = "inout Array<";
            SgType* baseType = array.get_base_type();
            sidlParameterPassingMechanim += TransformationSupport::getTypeName(baseType);
            sidlParameterPassingMechanim += ",1>";
            //FIXME: I don't see a way to determine the dimention of the array
        }



        // Build the substring for each parameter

        parameterTypesAndNames += sidlParameterPassingMechanim;
        parameterTypesAndNames += " ";

        //if(type->variantT() != V_SgTypeGlobalVoid)
        //{
        if(type->variantT() == V_SgTypeEllipse)
        {
            parameterTypesAndNames += "Array<BabelBaseType,1> "; //FIXME: need to include a declaration for BaseType
            parameterTypesAndNames += "elips" +  argumentCounter; //this fails to actually append the counter, but I don't think it will matter: kmk
        }
        else
        {
            SgName name = (*i)->get_name();
            string nameString = name.str();
            string typeName = TransformationSupport::getTypeName(type);

            if(typeName == "void")
            {
                if(nameString!="")
                {
                    parameterTypesAndNames += "opaque ";
                    parameterTypesAndNames += nameString;
                }
            }
            else
            {
                parameterTypesAndNames += typeName;
                parameterTypesAndNames += " ";
                if(nameString != "") //will be empty if the function declaration doesn't provide a name
                    parameterTypesAndNames += nameString;
            }
        }

        // Add a "," to the string if there are more parameters in the list
        if ( argumentCounter < argumentList.size()-1 )
            parameterTypesAndNames += ",";
        //}else printf("avoiding the void\n");
        argumentCounter++;
    }

    SgType* returnType = functionType->get_return_type();
    ROSE_ASSERT (returnType != NULL);
    string returnTypeName = "void";
    if(returnType->variantT() != V_SgTypeVoid)
        returnTypeName = TransformationSupport::getTypeName(returnType);


    string sidlMemberFunctionDeclaration = "          $RETURN_TYPE $FUNCTION_NAME($PARAMETERS);\n";

    sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$RETURN_TYPE" , returnTypeName );
    sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$FUNCTION_NAME" , sidlFunctionName );
    sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$PARAMETERS" , parameterTypesAndNames );


    return sidlMemberFunctionDeclaration;
}