예제 #1
0
void
SgClassDefinition::fixupCopy_symbols(SgNode* copy, SgCopyHelp & help) const
   {
#if DEBUG_FIXUP_COPY
     printf ("Inside of SgClassDefinition::fixupCopy_symbols() for class = %s class definition %p = %s copy = %p \n",this->get_declaration()->get_name().str(),this,this->class_name().c_str(),copy);
#endif

     SgClassDefinition* classDefinition_copy = isSgClassDefinition(copy);
     ROSE_ASSERT(classDefinition_copy != NULL);

     SgBaseClassPtrList::const_iterator i_original = this->get_inheritances().begin();
     SgBaseClassPtrList::iterator i_copy           = classDefinition_copy->get_inheritances().begin();
     ROSE_ASSERT(this->get_inheritances().size() == classDefinition_copy->get_inheritances().size());

     while ( (i_original != this->get_inheritances().end()) && (i_copy != classDefinition_copy->get_inheritances().end()) )
        {
       // Check the parent pointer to make sure it is properly set
          ROSE_ASSERT( (*i_original)->get_parent() != NULL);
          ROSE_ASSERT( (*i_original)->get_parent() == this);

          (*i_original)->fixupCopy_symbols(*i_copy,help);

       // DQ (11/7/2007): This was already setup on fixupCopy_scopes, but we can test it here.
       // (*i_copy)->set_parent(classDefinition_copy);
          ROSE_ASSERT( (*i_copy)->get_parent() != NULL);
          ROSE_ASSERT( (*i_copy)->get_parent() == classDefinition_copy);

          i_original++;
          i_copy++;
        }

     const SgDeclarationStatementPtrList & statementList_original = this->getDeclarationList();
     const SgDeclarationStatementPtrList & statementList_copy     = classDefinition_copy->getDeclarationList();

     SgDeclarationStatementPtrList::const_iterator j_original = statementList_original.begin();
     SgDeclarationStatementPtrList::const_iterator j_copy     = statementList_copy.begin();

  // Iterate over both lists to match up the correct pairs of SgStatement objects
     while ( (j_original != statementList_original.end()) && (j_copy != statementList_copy.end()) )
        {
          (*j_original)->fixupCopy_symbols(*j_copy,help);

          j_original++;
          j_copy++;
        }

  // Call the base class fixupCopy member function
     SgScopeStatement::fixupCopy_symbols(copy,help);

  // printf ("\nLeaving SgClassDefinition::fixupCopy_symbols() this = %p = %s  copy = %p \n",this,this->class_name().c_str(),copy);
   }
예제 #2
0
void
CompassAnalyses::StaticConstructorInitialization::Traversal::
visit(SgNode* node)
   { 
  // Test for static initialization of variables of type class, such initializations where they are 
  // static or appear in global scope can be called in an order dependent upon the compiler and this 
  // can lead to subtle bugs in large scale applications.

     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global or namespace variable or an static class member
                 // This might also have to be a test for other scopes as well.
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL || isSgNamespaceDefinitionStatement(scope) != NULL)
                       {
                      // printf ("Found a global variable defining a class = %p \n",initializedName);
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         output->addOutput(new CheckerOutput(initializedName));
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                           // printf ("Found a static data member defining a class = %p \n",initializedName);
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              output->addOutput(new CheckerOutput(initializedName));
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }

   } //End of the visit function.
// Returns true if the function declaration is declared virtual in
// some parent class, regardless of whether it is declared virtual
// in its own class.
bool isDeclaredVirtualWithinAncestor(SgFunctionDeclaration *functionDeclaration)
{
  SgMemberFunctionDeclaration *memberFunctionDeclaration =
    isSgMemberFunctionDeclaration(functionDeclaration);
  if ( memberFunctionDeclaration == NULL )
    return false;

  SgClassDefinition *classDefinition = 
    isSgClassDefinition(memberFunctionDeclaration->get_scope());
  ROSE_ASSERT(classDefinition != NULL);

  return isDeclaredVirtualWithinClassAncestry(functionDeclaration,
					      classDefinition);
}
예제 #4
0
void
Traversal::visit(SgNode* node)
   {
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

  // Look for variable declarations appearing in global scope!
  // if (variableDeclaration != NULL && isSgGlobal(variableDeclaration->get_parent()) != NULL)
     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global variable or an static class member
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL)
                       {
                         printf ("Found a global variable defining a class \n");
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         outputPositionInformation(variableDeclaration);
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                              printf ("Found a static data member defining a class \n");
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              outputPositionInformation(variableDeclaration);
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }
   }
예제 #5
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;
    }    
예제 #6
0
파일: helpFunctions.C 프로젝트: 8l/rose
/*  The function:
 *      getScopeString()
 *  makes a string which represents the scopes of a SgNode*. If a
 *  SgScopeStatement is inputted this will be included in the string.
 *  The form is:
 *     Scope N :: Scope N-1 :: .... :: Scope 1 :: Scope 0 ::
 *  where scope N is the topmost scope.
 */
string 
getScopeString(SgNode* astNode)
{
  ostringstream*   scopes = new ostringstream();
  (*scopes) << " "; 

  SgNodePtrVector scopesVector = findScopes(astNode);
  SgClassDeclaration* sageClassDeclaration;

  for(int i = scopesVector.size()-1; i >= 0 ; i--)
    {
      if(scopesVector[i]->variantT() == V_SgClassDefinition)
        {
          sageClassDeclaration = isSgClassDefinition(scopesVector[i])->get_declaration();
          (*scopes) << TransformationSupport::getTypeName(sageClassDeclaration->get_type()) << "::";
        }
    }
  return scopes->str();
}
예제 #7
0
void ModelBuilder::add(Model::model_t & model, SgVariableSymbol * variable_symbol) {
  SgScopeStatement * scope = variable_symbol->get_scope();
  assert(scope != NULL);

  SgNamespaceDefinitionStatement * nsp_defn     = isSgNamespaceDefinitionStatement(scope);
  SgClassDefinition              * class_defn   = isSgClassDefinition(scope);
  SgGlobal                       * global_scope = isSgGlobal(scope);
  
  SgType * sg_type = variable_symbol->get_type();
  assert(sg_type != NULL);
  Model::type_t type = model.lookup_type(sg_type);
  if (type == NULL) {
    add(model, sg_type);
    type = model.lookup_type(sg_type);
  }
  assert(type != NULL);
  
  if (nsp_defn != NULL || global_scope != NULL) {
    Model::variable_t element = Model::build<Model::e_model_variable>();

    element->node->symbol = variable_symbol;
    element->node->type = type;
  
    setParentFromScope<Model::e_model_variable>(model, element, variable_symbol);

    model.variables.push_back(element);
  }
  else if (class_defn != NULL) {
    Model::field_t element = Model::build<Model::e_model_field>();

    element->node->symbol = variable_symbol;
    element->node->type = type;
  
    setParentFromScope<Model::e_model_field>(model, element, variable_symbol);

    model.fields.push_back(element);
  }
  else {
    /// \todo error printing
    assert(false);
  }
}
bool Driver<Sage>::resolveValidParent<SgMemberFunctionSymbol>(SgMemberFunctionSymbol * symbol) {
  SgClassSymbol * parent = NULL;
  
  if (p_valid_symbols.find(symbol) != p_valid_symbols.end()) return true;

  SgClassDefinition * class_scope = isSgClassDefinition(symbol->get_scope());
  if (class_scope != NULL) {
    SgClassDeclaration * parent_decl = class_scope->get_declaration();
    assert(parent_decl != NULL);
    parent = SageInterface::lookupClassSymbolInParentScopes(parent_decl->get_name(), parent_decl->get_scope());
    assert(parent != NULL);

    if (!resolveValidParent<SgClassSymbol>((SgClassSymbol *)parent)) return false;
    assert(p_valid_symbols.find(parent) != p_valid_symbols.end());
  }

  p_valid_symbols.insert(symbol);
  p_parent_map.insert(std::pair<SgSymbol *, SgSymbol *>(symbol, parent));
  p_member_function_symbols.insert(symbol);

  return true;
}
Sage<SgMemberFunctionDeclaration>::build_scopes_t Driver<Sage>::getBuildScopes<SgMemberFunctionDeclaration>(const Sage<SgMemberFunctionDeclaration>::object_desc_t & desc) {
  Sage<SgMemberFunctionDeclaration>::build_scopes_t result;

  assert(desc.parent != NULL);

  {
    SgClassDeclaration * class_decl = desc.parent->get_declaration();
    assert(class_decl != NULL);
    class_decl = isSgClassDeclaration(class_decl->get_definingDeclaration());
    assert(class_decl != NULL);
    SgClassDefinition * class_defn = isSgClassDefinition(class_decl->get_definition());
    assert(class_defn != NULL);
    result.decl_scope = class_defn;
  }

  if (desc.create_definition) {
    size_t file_id = desc.file_id;

    if (file_id == 0) {
      std::map<SgSymbol *, size_t>::iterator it_symbol_to_file_id = p_symbol_to_file_id_map.find(desc.parent);
      assert(it_symbol_to_file_id != p_symbol_to_file_id_map.end());

      file_id = it_symbol_to_file_id->second;
    }
    assert(file_id != 0);

    std::map<size_t, SgSourceFile *>::iterator it_file = id_to_file_map.find(file_id);
    assert(it_file != id_to_file_map.end());
    SgSourceFile * defn_file = it_file->second;
    assert(defn_file != NULL);

    result.defn_scope = defn_file->get_globalScope();
  }
  else result.defn_scope = NULL;

  return result;
}
예제 #10
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.
예제 #11
0
void ModelBuilder::setParentFromScope(Model::model_t & model, Model::element_t<kind> * element, SgSymbol * symbol) {
  SgScopeStatement * scope = symbol->get_scope();
  assert(scope != NULL);

  SgNamespaceDefinitionStatement * nsp_defn     = isSgNamespaceDefinitionStatement(scope);
  SgClassDefinition              * class_defn   = isSgClassDefinition(scope);
  SgGlobal                       * global_scope = isSgGlobal(scope);

  if (nsp_defn != NULL) {
    // field and method cannot have namespace for scope
    assert(kind != Model::e_model_field && kind != Model::e_model_method);
  
    SgNamespaceDeclarationStatement * nsp_decl = nsp_defn->get_namespaceDeclaration();
    assert(nsp_decl != NULL);
    
    SgNamespaceSymbol * parent_symbol = isSgNamespaceSymbol(nsp_decl->get_symbol_from_symbol_table());
    assert(parent_symbol != NULL);
    
    Model::namespace_t parent_element = model.lookup_namespace(parent_symbol);
    if (parent_element == NULL) {
      add(model, parent_symbol);
      parent_element = model.lookup_namespace(parent_symbol);
    }
    assert(parent_element != NULL);
    
    switch (kind) {
      case Model::e_model_variable:  parent_element->scope->variable_children.push_back  ( (Model::variable_t)  element); break;
      case Model::e_model_function:  parent_element->scope->function_children.push_back  ( (Model::function_t)  element); break;
      case Model::e_model_type:      parent_element->scope->type_children.push_back      ( (Model::type_t)      element); break;
      case Model::e_model_class:     parent_element->scope->class_children.push_back     ( (Model::class_t)     element); break;
      case Model::e_model_namespace: parent_element->scope->namespace_children.push_back ( (Model::namespace_t) element); break;

      case Model::e_model_field:
      case Model::e_model_method:
        assert(false);
    }
    
    switch (kind) {
      case Model::e_model_variable:  ( (Model::variable_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_function:  ( (Model::function_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_namespace: ( (Model::namespace_t) element)->scope->parent = parent_element; break;

      case Model::e_model_type:  ( (Model::type_t)  element)->scope->parent.a_namespace = parent_element; break;
      case Model::e_model_class: ( (Model::class_t) element)->scope->parent.a_namespace = parent_element; break;

      case Model::e_model_field:
      case Model::e_model_method:
        assert(false);
    }
  }
  else if (class_defn != NULL) {
    // namespace, function, and variable cannot have class for scope
    assert(kind != Model::e_model_namespace && kind != Model::e_model_function && kind != Model::e_model_variable);
    
    SgClassDeclaration * class_decl = class_defn->get_declaration();
    assert(class_decl != NULL);
    
    SgClassSymbol * parent_symbol = isSgClassSymbol(class_decl->get_firstNondefiningDeclaration()->get_symbol_from_symbol_table());
    assert(parent_symbol != NULL);
    
    Model::class_t parent_element = model.lookup_class(parent_symbol);
    if (parent_element == NULL) {
      add(model, parent_symbol);
      parent_element = model.lookup_class(parent_symbol);
    }
    assert(parent_element != NULL);

    switch (kind) {
      case Model::e_model_field:  parent_element->scope->field_children.push_back  ( (Model::field_t)  element); break;
      case Model::e_model_method: parent_element->scope->method_children.push_back ( (Model::method_t) element); break;
      case Model::e_model_type:   parent_element->scope->type_children.push_back   ( (Model::type_t)   element); break;
      case Model::e_model_class:  parent_element->scope->class_children.push_back  ( (Model::class_t)  element); break;

      case Model::e_model_namespace:
      case Model::e_model_variable:
      case Model::e_model_function:
        assert(false);
    }

    switch (kind) {
      case Model::e_model_field:  ( (Model::field_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_method: ( (Model::method_t) element)->scope->parent = parent_element; break;
      
      case Model::e_model_type:  ( (Model::type_t)  element)->scope->parent.a_class = parent_element; break;
      case Model::e_model_class: ( (Model::class_t) element)->scope->parent.a_class = parent_element; break;

      case Model::e_model_namespace:
      case Model::e_model_variable:
      case Model::e_model_function:
        assert(false);
    }
  }
  else if (global_scope != NULL) {
    /// \todo Should we have a root namespace to represent the global scope ???
  }
  else {
    /// \todo error printing
    assert(false);
  }
}
예제 #12
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++;
        }

   }
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
   }
예제 #14
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;
}
int main(int argc, char **argv)
{
  SgProject *project = frontend(argc, argv);
  
  // Instantiate a class hierarchy wrapper.
  ClassHierarchyWrapper classHierarchy( project );

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

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

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

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

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

  }

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

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

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

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

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

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

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

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

      }

    }
    

  }

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

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

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

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

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


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

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

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

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

    }

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

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

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

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

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

    SgClassDefinitionPtrList subclasses = 
      classHierarchy.getSubclasses(classDefinition);

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

    }

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

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

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

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

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

    // We are only interested in examining method invocations.
    bool isDotExp = false;
    if ( !isMethodCall(functionCallExp, isDotExp) )
      continue;
    
    numCallSites++;
    // Certainly can be resolved to the static method.
    numPossibleResolutions++;

    if ( isDotExp ) {
      // If this is a dot expression (i.e., a.foo()), we can
      // statically determine its type.
      numMonomorphicCallSites++;
      continue;
    }

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

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

    unsigned int numOverridesForMethod = 0;

    if ( ( isVirtual(functionDeclaration) ) ||
	 ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) {
      
      SgClassDefinition *classDefinition = 
	isSgClassDefinition(memberFunctionDeclaration->get_scope());
      ROSE_ASSERT(classDefinition != NULL);
      
      SgClassDefinitionPtrList subclasses = 
	classHierarchy.getSubclasses(classDefinition);

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

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

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

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

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

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

	  // Determine whether subclass of the class defining this
	  // method overrides the method.
	  if ( methodOverridesVirtualMethod(method, 
					    memberFunctionDeclaration) ) {
	    numOverridesForMethod++;
	  }

	}

      }

      if ( numOverridesForMethod == 0 )
	numMonomorphicCallSites++;
      numPossibleResolutions += numOverridesForMethod;

      std::cout << "Method invocation has " << numOverridesForMethod + 1 << " possible resolutions " << std::endl;
      std::cout << functionCallExp->unparseToCompleteString() << std::endl;

    }

  }
#endif
#endif
  return 0;
}
예제 #16
0
void
ProcTraversal::visit(SgNode *node) {
    if (isSgFunctionDeclaration(node)) {
        SgFunctionDeclaration *decl = isSgFunctionDeclaration(node);
        if (decl->get_definition() != NULL) {
            /* collect statistics */
            //AstNumberOfNodesStatistics anons;
            //anons.traverse(decl, postorder);
            //original_ast_nodes += anons.get_numberofnodes();
            //original_ast_statements += anons.get_numberofstatements();

            /* do the real work */
            Procedure *proc = new Procedure();
            proc->procnum = procnum++;
            proc->decl = decl;
            proc->funcsym
                = isSgFunctionSymbol(decl->get_symbol_from_symbol_table());
            if (proc->funcsym == NULL)
            {
#if 0
                std::cout
                        << std::endl
                        << "*** NULL function symbol for declaration "
                        << decl->unparseToString()
                        << std::endl
                        << "symbol: "
                        << (void *) decl->get_symbol_from_symbol_table()
                        << (decl->get_symbol_from_symbol_table() != NULL ?
                            decl->get_symbol_from_symbol_table()->class_name()
                            : "")
                        << std::endl
                        << "first nondef decl: "
                        << (void *) decl->get_firstNondefiningDeclaration()
                        << " sym: "
                        << (decl->get_firstNondefiningDeclaration() != NULL ?
                            (void *) decl->get_firstNondefiningDeclaration()
                            ->get_symbol_from_symbol_table()
                            : (void *) NULL)
                        << std::endl;
#endif
                if (decl->get_firstNondefiningDeclaration() != NULL)
                {
                    proc->funcsym = isSgFunctionSymbol(decl
                                                       ->get_firstNondefiningDeclaration()
                                                       ->get_symbol_from_symbol_table());
                }
            }
            assert(proc->funcsym != NULL);
            // GB (2008-05-14): We need two parameter lists: One for the names of the
            // variables inside the function definition, which is
            // decl->get_parameterList(), and one that contains any default arguments
            // the function might have. The default arguments are supposedly
            // associated with the first nondefining declaration.
            proc->params = decl->get_parameterList();
            SgDeclarationStatement *fndstmt = decl->get_firstNondefiningDeclaration();
            SgFunctionDeclaration *fnd = isSgFunctionDeclaration(fndstmt);
            if (fnd != NULL && fnd != decl)
                proc->default_params = fnd->get_parameterList();
            else
                proc->default_params = proc->params;

            SgMemberFunctionDeclaration *mdecl
                = isSgMemberFunctionDeclaration(decl);
            if (mdecl) {
                proc->class_type = isSgClassDefinition(mdecl->get_scope());
                std::string name = proc->class_type->get_mangled_name().str();
                name += "::";
                name += decl->get_name().str();
                std::string mname = proc->class_type->get_mangled_name().str();
                mname += "::";
                mname += decl->get_mangled_name().str();
                proc->memberf_name = name;
                proc->mangled_memberf_name = mname;
                proc->name = decl->get_name().str();
                proc->mangled_name = decl->get_mangled_name().str();
                // GB (2008-05-26): Computing a single this symbol for each
                // procedure. Thus, this symbol can also be compared by pointer
                // equality (as is the case for all other symbols). While we're at it,
                // we also build a VarRefExp for this which can be used everywhere the
                // this pointer occurs.
                proc->this_type = Ir::createPointerType(
                                      proc->class_type->get_declaration()->get_type());
                proc->this_sym = Ir::createVariableSymbol("this", proc->this_type);
                proc->this_exp = Ir::createVarRefExp(proc->this_sym);
            } else {
                proc->name = decl->get_name().str();
                proc->mangled_name = decl->get_mangled_name().str();
                proc->class_type = NULL;
                proc->memberf_name = proc->mangled_memberf_name = "";
                proc->this_type = NULL;
                proc->this_sym = NULL;
                proc->this_exp = NULL;
                // GB (2008-07-01): Better resolution of calls to static functions.
                // This only makes sense for non-member functions.
                SgStorageModifier &sm =
                    (fnd != NULL ? fnd : decl)->get_declarationModifier().get_storageModifier();
                proc->isStatic = sm.isStatic();
                // Note that we query the first nondefining declaration for the
                // static modifier, but we save the file of the *defining*
                // declaration. This is because the first declaration might be in
                // some header file, but for call resolution, the actual source
                // file with the definition is relevant.
                // Trace back to the enclosing file node. The definition might be
                // included in foo.c from bar.c, in which case the Sg_File_Info
                // would refer to bar.c; but for function call resolution, foo.c is
                // the relevant file.
                SgNode *p = decl->get_parent();
                while (p != NULL && !isSgFile(p))
                    p = p->get_parent();
                proc->containingFile = isSgFile(p);
            }
            proc_map.insert(std::make_pair(proc->name, proc));
            mangled_proc_map.insert(std::make_pair(proc->mangled_name, proc));
            std::vector<SgVariableSymbol* >* arglist
                = new std::vector<SgVariableSymbol* >();
            SgVariableSymbol *this_var = NULL, *this_temp_var = NULL;
            if (mdecl
                    || decl->get_parameterList() != NULL
                    && !decl->get_parameterList()->get_args().empty()) {
                proc->arg_block
                    = new BasicBlock(node_id, INNER, proc->procnum);
                if (mdecl) {
                    // GB (2008-05-26): We now compute the this pointer right at the
                    // beginning of building the procedure.
                    // this_var = Ir::createVariableSymbol("this", this_type);
                    this_var = proc->this_sym;
                    // std::string varname
                    //   = std::string("$") + proc->name + "$this";
                    // this_temp_var = Ir::createVariableSymbol(varname, proc->this_type);
                    this_temp_var = global_this_variable_symbol;
                    ParamAssignment* paramAssignment
                        = Ir::createParamAssignment(this_var, this_temp_var);
                    proc->arg_block->statements.push_back(paramAssignment);
                    arglist->push_back(this_var);
                    if (proc->name.find('~') != std::string::npos) {
                        arglist->push_back(this_temp_var);
                    }
                }
                SgInitializedNamePtrList params
                    = proc->params->get_args();
                SgInitializedNamePtrList::const_iterator i;
#if 0
                int parnum = 0;
                for (i = params.begin(); i != params.end(); ++i) {
                    SgVariableSymbol *i_var = Ir::createVariableSymbol(*i);
                    std::stringstream varname;
                    // varname << "$" << proc->name << "$arg_" << parnum++;
                    SgVariableSymbol* var =
                        Ir::createVariableSymbol(varname.str(),(*i)->get_type());
                    proc->arg_block->statements.push_back(Ir::createParamAssignment(i_var, var));
                    arglist->push_back(i_var);
                }
#else
                // GB (2008-06-23): Trying to replace all procedure-specific argument
                // variables by a global list of argument variables. This means that at
                // this point, we do not necessarily need to build a complete list but
                // only add to the CFG's argument list if it is not long enough.
                size_t func_params = params.size();
                size_t global_args = global_argument_variable_symbols.size();
                std::stringstream varname;
                while (global_args < func_params)
                {
                    varname.str("");
                    varname << "$tmpvar$arg_" << global_args++;
                    SgVariableSymbol *var
                        = Ir::createVariableSymbol(varname.str(),
                                                   global_unknown_type);
                    program->global_map[varname.str()]
                        = std::make_pair(var, var->get_declaration());
                    global_argument_variable_symbols.push_back(var);
                }
                // now create the param assignments
                size_t j = 0;
                for (i = params.begin(); i != params.end(); ++i)
                {
                    SgVariableSymbol *i_var = Ir::createVariableSymbol(params[j]);
                    SgVariableSymbol *var = global_argument_variable_symbols[j];
                    j++;
                    proc->arg_block->statements.push_back(
                        Ir::createParamAssignment(i_var, var));
                    arglist->push_back(i_var);
                }
#if 0
                // replace the arglist allocated above by the new one; this must be
                // fixed for this pointers!
                delete arglist;
                arglist = &global_argument_variable_symbols;
#endif
#endif
            } else {
                proc->arg_block = NULL;
            }
            /* If this is a constructor, call default constructors
             * of all base classes. If base class constructors are
             * called manually, these calls will be removed later. */
            if (mdecl
                    && strcmp(mdecl->get_name().str(),
                              proc->class_type->get_declaration()->get_name().str()) == 0
                    && proc->class_type != NULL) {
                SgBaseClassPtrList::iterator base;
                for (base = proc->class_type->get_inheritances().begin();
                        base != proc->class_type->get_inheritances().end();
                        ++base) {
                    SgClassDeclaration* baseclass = (*base)->get_base_class();
                    SgVariableSymbol *lhs
                        = Ir::createVariableSymbol("$tmpvar$" + baseclass->get_name(),
                                                   baseclass->get_type());
                    program->global_map["$tmpvar$" + baseclass->get_name()]
                        = std::make_pair(lhs, lhs->get_declaration());
                    SgMemberFunctionDeclaration* fd=get_default_constructor(baseclass);
                    assert(fd);
                    SgType* basetype=baseclass->get_type();
                    assert(basetype);
                    SgConstructorInitializer *sci
                        = Ir::createConstructorInitializer(fd,basetype);
                    ArgumentAssignment* a
                        = Ir::createArgumentAssignment(lhs, sci);
                    proc->arg_block->statements.push_back(a);

                    // std::string this_called_varname
                    //   = std::string("$") + baseclass->get_name() + "$this";
                    SgVariableSymbol *this_called_var
                    // = Ir::createVariableSymbol(this_called_varname,
                    //                            baseclass->get_type());
                        = global_this_variable_symbol;
                    ReturnAssignment* this_ass
                        = Ir::createReturnAssignment(this_var, this_called_var);
                    proc->arg_block->statements.push_back(this_ass);
                }
            }
            if (mdecl && mdecl->get_CtorInitializerList() != NULL
                    && !mdecl->get_CtorInitializerList()->get_ctors().empty()) {
                SgInitializedNamePtrList cis
                    = mdecl->get_CtorInitializerList()->get_ctors();
                SgInitializedNamePtrList::const_iterator i;
                if (proc->arg_block == NULL) {
                    proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum);
                }
                for (i = cis.begin(); i != cis.end(); ++i) {
                    SgVariableSymbol* lhs = Ir::createVariableSymbol(*i);
                    SgAssignInitializer *ai
                        = isSgAssignInitializer((*i)->get_initializer());
                    SgConstructorInitializer *ci
                        = isSgConstructorInitializer((*i)->get_initializer());
                    /* TODO: other types of initializers */
                    if (ai) {
                        SgClassDeclaration *class_decl
                            = proc->class_type->get_declaration();
                        // GB (2008-05-26): We now compute the this pointer right at the
                        // beginning of building the procedure.
                        // SgVarRefExp* this_ref
                        //   = Ir::createVarRefExp("this",
                        //                         Ir::createPointerType(class_decl->get_type()));
                        SgVarRefExp* this_ref = proc->this_exp;
                        SgArrowExp* arrowExp
                            = Ir::createArrowExp(this_ref,Ir::createVarRefExp(lhs));
                        // GB (2008-03-17): We need to handle function calls in
                        // initializers. In order to be able to build an argument
                        // assignment, we need to know the function's return variable, so
                        // the expression labeler must be called on it. The expression
                        // number is irrelevant, however, as it does not appear in the
                        // return variable.
                        if (isSgFunctionCallExp(ai->get_operand_i())) {
#if 0
                            ExprLabeler el(0 /*expnum*/);
                            el.traverse(ai->get_operand_i(), preorder);
                            // expnum = el.get_expnum();
#endif
                            // GB (2008-06-25): There is now a single global return
                            // variable. This may or may not mean that we can simply ignore
                            // the code above. I don't quite understand why this labeling
                            // couldn't be done later on, and where its result was used.
                        }
                        ArgumentAssignment* argumentAssignment
                            = Ir::createArgumentAssignment(arrowExp,ai->get_operand_i());
                        proc->arg_block->statements.push_back(argumentAssignment);
                    } else if (ci) {
                        /* if this is a call to a base class's
                         * constructor, remove the call we generated
                         * before */
                        SgStatement* this_a = NULL;
                        SgClassDeclaration* cd = ci->get_class_decl();
                        std::deque<SgStatement *>::iterator i;
                        for (i = proc->arg_block->statements.begin();
                                i != proc->arg_block->statements.end();
                                ++i) {
                            ArgumentAssignment* a
                                = dynamic_cast<ArgumentAssignment *>(*i);
                            if (a && isSgConstructorInitializer(a->get_rhs())) {
                                SgConstructorInitializer* c
                                    = isSgConstructorInitializer(a->get_rhs());
                                std::string c_decl_name = c->get_class_decl()->get_name().str();
                                std::string cd_name = cd->get_name().str();
                                // if (c->get_class_decl()->get_name() == cd->get_name()) {
                                if (c_decl_name == cd_name) {
#if 0
                                    // erase the following assignment
                                    // of the this pointer as well
                                    this_a = *proc->arg_block->statements.erase(i+1);
                                    proc->arg_block->statements.erase(i);
#endif
                                    // GB (2008-03-28): That's an interesting piece of code, but
                                    // it might be very mean to iterators. At least it is hard to
                                    // see whether it is correct. So let's try it like this:
                                    // erase i; we get an iterator back, which refers to the next
                                    // element. Save that element as this_a, and then erase.
                                    std::deque<SgStatement *>::iterator this_pos;
                                    this_pos = proc->arg_block->statements.erase(i);
                                    this_a = *this_pos;
                                    proc->arg_block->statements.erase(this_pos);
                                    // Good. Looks like this fixed a very obscure bug.
                                    break;
                                }
                            }
                        }
                        /* now add the initialization */
                        proc->arg_block->statements.push_back(Ir::createArgumentAssignment(lhs, ci));
                        if (this_a != NULL)
                            proc->arg_block->statements.push_back(this_a);
                    }
                }
            }
            proc->entry = new CallBlock(node_id++, START, proc->procnum,
                                        new std::vector<SgVariableSymbol *>(*arglist),
                                        (proc->memberf_name != ""
                                         ? proc->memberf_name
                                         : proc->name));
            proc->exit = new CallBlock(node_id++, END, proc->procnum,
                                       new std::vector<SgVariableSymbol *>(*arglist),
                                       (proc->memberf_name != ""
                                        ? proc->memberf_name
                                        : proc->name));
            proc->entry->partner = proc->exit;
            proc->exit->partner = proc->entry;
            proc->entry->call_target = Ir::createFunctionRefExp(proc->funcsym);
            proc->exit->call_target = Ir::createFunctionRefExp(proc->funcsym);
            /* In constructors, insert an assignment $A$this = this
             * at the end to make sure that the 'this' pointer can be
             * passed back to the calling function uncobbled. */
            proc->this_assignment = NULL;
            if (mdecl) {
                SgMemberFunctionDeclaration* cmdecl
                    = isSgMemberFunctionDeclaration(mdecl->get_firstNondefiningDeclaration());
                // if (cmdecl && cmdecl->get_specialFunctionModifier().isConstructor()) {
                proc->this_assignment
                    = new BasicBlock(node_id++, INNER, proc->procnum);
                ReturnAssignment* returnAssignment
                    = Ir::createReturnAssignment(this_temp_var, this_var);
                proc->this_assignment->statements.push_back(returnAssignment);
                add_link(proc->this_assignment, proc->exit, NORMAL_EDGE);
                // }
            }
            std::stringstream varname;
            // varname << "$" << proc->name << "$return";
            // proc->returnvar = Ir::createVariableSymbol(varname.str(),
            //                                            decl->get_type()->get_return_type());
            proc->returnvar = global_return_variable_symbol;
            procedures->push_back(proc);
            if(getPrintCollectedFunctionNames()) {
                std::cout << (proc->memberf_name != ""
                              ? proc->memberf_name
                              : proc->name)
                          << " " /*<< proc->decl << std::endl*/;
            }
            if (proc->arg_block != NULL)
            {
                proc->arg_block->call_target
                    = Ir::createFunctionRefExp(proc->funcsym);
            }
            // delete arglist;
        }
    }
}
예제 #17
0
bool ClangToSageTranslator::VisitRecordDecl(clang::RecordDecl * record_decl, SgNode ** node) {
#if DEBUG_VISIT_DECL
    std::cerr << "ClangToSageTranslator::VisitRecordDecl" << std::endl;
#endif

    // FIXME May have to check the symbol table first, because of out-of-order traversal of C++ classes (Could be done in CxxRecord class...)

    bool res = true;

    SgClassDeclaration * sg_class_decl = NULL;

  // Find previous declaration

    clang::RecordDecl * prev_record_decl = record_decl->getPreviousDeclaration();
    SgClassSymbol * sg_prev_class_sym = isSgClassSymbol(GetSymbolFromSymbolTable(prev_record_decl));
    SgClassDeclaration * sg_prev_class_decl = sg_prev_class_sym == NULL ? NULL : isSgClassDeclaration(sg_prev_class_sym->get_declaration());

    SgClassDeclaration * sg_first_class_decl = sg_prev_class_decl == NULL ? NULL : isSgClassDeclaration(sg_prev_class_decl->get_firstNondefiningDeclaration());
    SgClassDeclaration * sg_def_class_decl = sg_prev_class_decl == NULL ? NULL : isSgClassDeclaration(sg_prev_class_decl->get_definingDeclaration());

    ROSE_ASSERT(sg_first_class_decl != NULL || sg_def_class_decl == NULL);

    bool had_prev_decl = sg_first_class_decl != NULL;

  // Name

    SgName name(record_decl->getNameAsString());

  // Type of class

    SgClassDeclaration::class_types type_of_class;
    switch (record_decl->getTagKind()) {
        case clang::TTK_Struct:
            type_of_class = SgClassDeclaration::e_struct;
            break;
        case clang::TTK_Class:
            type_of_class = SgClassDeclaration::e_class;
            break;
        case clang::TTK_Union:
            type_of_class = SgClassDeclaration::e_union;
            break;
        default:
            std::cerr << "Runtime error: RecordDecl can only be a struct/class/union." << std::endl;
            res = false;
    }

  // Build declaration(s)

    sg_class_decl = new SgClassDeclaration(name, type_of_class, NULL, NULL);

    sg_class_decl->set_scope(SageBuilder::topScopeStack());
    sg_class_decl->set_parent(SageBuilder::topScopeStack());

    SgClassType * type = NULL;
    if (sg_first_class_decl != NULL) {
        type = sg_first_class_decl->get_type();
    }
    else {
        type = SgClassType::createType(sg_class_decl);
    }
    ROSE_ASSERT(type != NULL);
    sg_class_decl->set_type(type);

    if (record_decl->isAnonymousStructOrUnion()) sg_class_decl->set_isUnNamed(true);

    if (!had_prev_decl) {
        sg_first_class_decl = sg_class_decl;
        sg_first_class_decl->set_firstNondefiningDeclaration(sg_first_class_decl);
        sg_first_class_decl->set_definingDeclaration(NULL);
        sg_first_class_decl->set_definition(NULL);
        sg_first_class_decl->setForward();
        if (!record_decl->field_empty()) {
            sg_def_class_decl = new SgClassDeclaration(name, type_of_class, type, NULL);
            sg_def_class_decl->set_scope(SageBuilder::topScopeStack());
            if (record_decl->isAnonymousStructOrUnion()) sg_def_class_decl->set_isUnNamed(true);
            sg_def_class_decl->set_parent(SageBuilder::topScopeStack());

            sg_class_decl = sg_def_class_decl; // we return thew defining decl

            sg_def_class_decl->set_firstNondefiningDeclaration(sg_first_class_decl);
            sg_def_class_decl->set_definingDeclaration(sg_def_class_decl);

            sg_first_class_decl->set_definingDeclaration(sg_def_class_decl);
            setCompilerGeneratedFileInfo(sg_first_class_decl);
        }
    }
    else if (!record_decl->field_empty()) {
        if (sg_def_class_decl != NULL) {
            delete sg_class_decl;
            *node = sg_def_class_decl;
            return true;
        }
        sg_def_class_decl = sg_class_decl;
        sg_def_class_decl->set_firstNondefiningDeclaration(sg_first_class_decl);
        sg_def_class_decl->set_definingDeclaration(sg_def_class_decl);
        sg_first_class_decl->set_definingDeclaration(sg_def_class_decl);
    }
    else // second (or more) non-defining declaration
        return false; // FIXME ROSE need only one non-defining declaration (SageBuilder don't let me build another one....)

  // Update symbol table

    if (!had_prev_decl) {
        SgScopeStatement * scope = SageBuilder::topScopeStack();
        SgClassSymbol * class_symbol = new SgClassSymbol(sg_first_class_decl);
        scope->insert_symbol(name, class_symbol);
    }

  // Build ClassDefinition

    if (!record_decl->field_empty()) {
        SgClassDefinition * sg_class_def = isSgClassDefinition(sg_def_class_decl->get_definition());
        if (sg_class_def == NULL) {
            sg_class_def = SageBuilder::buildClassDefinition_nfi(sg_def_class_decl);
        }
        sg_def_class_decl->set_definition(sg_class_def);

        ROSE_ASSERT(sg_class_def->get_symbol_table() != NULL);

        applySourceRange(sg_class_def, record_decl->getSourceRange());

        SageBuilder::pushScopeStack(sg_class_def);

        clang::RecordDecl::field_iterator it;
        for (it = record_decl->field_begin(); it != record_decl->field_end(); it++) {
            SgNode * tmp_field = Traverse(*it);
            SgDeclarationStatement * field_decl = isSgDeclarationStatement(tmp_field);
            ROSE_ASSERT(field_decl != NULL);
            sg_class_def->append_member(field_decl);
            field_decl->set_parent(sg_class_def);
        }

        SageBuilder::popScopeStack();
    }

    ROSE_ASSERT(sg_class_decl->get_definingDeclaration() == NULL || isSgClassDeclaration(sg_class_decl->get_definingDeclaration())->get_definition() != NULL);
    ROSE_ASSERT(sg_first_class_decl->get_definition() == NULL);
    ROSE_ASSERT(sg_def_class_decl == NULL || sg_def_class_decl->get_definition() != NULL);

    *node = sg_class_decl;

    return VisitTagDecl(record_decl, node) && res;
}
Sage<SgMemberFunctionDeclaration>::build_result_t Driver<Sage>::build<SgMemberFunctionDeclaration>(const Sage<SgMemberFunctionDeclaration>::object_desc_t & desc) {
  Sage<SgMemberFunctionDeclaration>::build_result_t result;

  Sage<SgMemberFunctionDeclaration>::build_scopes_t scopes = getBuildScopes<SgMemberFunctionDeclaration>(desc);
  
  SgScopeStatement * decl_scope = scopes.decl_scope;
  SgScopeStatement * defn_scope = scopes.defn_scope;

  assert(isSgClassDefinition(decl_scope));
  assert(decl_scope != defn_scope);

  // Build Declaration
  SgMemberFunctionDeclaration * mfunc_decl = NULL;
  {
    mfunc_decl = SageBuilder::buildNondefiningMemberFunctionDeclaration(desc.name, desc.return_type, desc.params, decl_scope, NULL, 0, false, NULL);
    SageInterface::appendStatement(mfunc_decl, decl_scope);

    if (desc.is_constructor)
      mfunc_decl->get_specialFunctionModifier().setConstructor();

    assert(mfunc_decl->get_definition() == NULL);
    assert(mfunc_decl->get_associatedClassDeclaration() != NULL);
  }

  // Build Definition
  SgMemberFunctionDeclaration * mfunc_defn = NULL;
  {
    mfunc_defn = SageBuilder::buildDefiningMemberFunctionDeclaration(desc.name, desc.return_type, desc.params, decl_scope, NULL, 0, false, mfunc_decl, NULL);
    SageInterface::appendStatement(mfunc_defn, defn_scope);

    if (desc.is_constructor)
      mfunc_defn->get_specialFunctionModifier().setConstructor();

    assert(mfunc_defn->get_associatedClassDeclaration() != NULL);

    result.definition = mfunc_defn->get_definition();
    assert(result.definition != NULL);
  }

  { // Symbol handling
    result.symbol = isSgMemberFunctionSymbol(decl_scope->lookup_function_symbol(desc.name));
    assert(result.symbol != NULL);

    std::map<SgSymbol *, size_t>::iterator it_symbol_to_file_id = p_symbol_to_file_id_map.find(desc.parent);
    assert(it_symbol_to_file_id != p_symbol_to_file_id_map.end());
    p_symbol_to_file_id_map.insert(std::pair<SgSymbol *, size_t>(result.symbol, it_symbol_to_file_id->second));

    p_valid_symbols.insert(result.symbol);
    p_parent_map.insert(std::pair<SgSymbol *, SgSymbol *>(result.symbol, desc.parent));
    p_member_function_symbols.insert(result.symbol);
  }

#if PATCHING_SAGE_BUILDER_ISSUES
  // Decl and Defn
  { 
    mfunc_decl->set_definingDeclaration(mfunc_defn);
    mfunc_decl->set_firstNondefiningDeclaration(mfunc_decl);

    mfunc_defn->set_definingDeclaration(mfunc_defn);
    mfunc_defn->set_firstNondefiningDeclaration(mfunc_decl);
  }
#endif

  return result;
}