Пример #1
0
Файл: options.C Проект: 8l/rose
void
TransformationSupport::getTransformationOptions ( SgNode* astNode, list<OptionDeclaration> & generatedList, string identifingTypeName )
   {
  // This function searches for variables of type ScopeBasedTransformationOptimization.  Variables
  // of type ScopeBasedTransformationOptimization are used to communicate optimizations from the
  // application to the preprocessor. If called from a project or file object it traverses down to
  // the global scope of the file and searches only the global scope, if called from and other
  // location within the AST it searches the current scope and then traverses the parent nodes to
  // find all enclosing scopes until in reaches the global scope.  At each scope it searches for
  // variables of type ScopeBasedTransformationOptimization.

  // printf ("######################### START OF TRANSFORMATION OPTION QUERY ######################## \n");

     ROSE_ASSERT (astNode != NULL);
     ROSE_ASSERT (identifingTypeName.c_str() != NULL);

#if 0
     printf ("In getTransformationOptions(): astNode->sage_class_name() = %s generatedList.size() = %d \n",
          astNode->sage_class_name(),generatedList.size());
     SgLocatedNode* locatedNode = isSgLocatedNode(astNode);
     if (locatedNode != NULL)
        {
          printf ("          locatedNode->get_file_info()->get_filename() = %s \n",locatedNode->get_file_info()->get_filename());
          printf ("          locatedNode->get_file_info()->get_line() = %d \n",locatedNode->get_file_info()->get_line());
        }
#endif

     switch (astNode->variant())
        {
          case ProjectTag:
             {
               SgProject* project = isSgProject(astNode);
               ROSE_ASSERT (project != NULL);

           //! Loop through all the files in the project and call the mainTransform function for each file
               int i = 0;
               for (i=0; i < project->numberOfFiles(); i++)
                  {
                    SgFile* file = &(project->get_file(i));

                 // printf ("Calling Query::traverse(SgFile,QueryFunctionType,QueryAssemblyFunctionType) \n");
                    getTransformationOptions ( file, generatedList, identifingTypeName );
                  }
               break;
             }

          case SourceFileTag:
             {
               SgSourceFile* file = isSgSourceFile(astNode);
               ROSE_ASSERT (file != NULL);
               SgGlobal* globalScope = file->get_globalScope();
               ROSE_ASSERT (globalScope != NULL);
               ROSE_ASSERT (isSgGlobal(globalScope) != NULL);
               getTransformationOptions ( globalScope, generatedList, identifingTypeName );
               break;
             }

       // Global Scope
          case GLOBAL_STMT:
             {
               SgGlobal* globalScope = isSgGlobal(astNode);
               ROSE_ASSERT (globalScope != NULL);

               SgSymbolTable* symbolTable = globalScope->get_symbol_table();
               ROSE_ASSERT (symbolTable != NULL);
               getTransformationOptions ( symbolTable, generatedList, identifingTypeName );

            // printf ("Processed global scope, exiting .. \n");
            // ROSE_ABORT();
               break;
             }

          case SymbolTableTag:
             {
            // List the variable in each scope
            // printf ("List all the variables in this symbol table! \n");
               SgSymbolTable* symbolTable = isSgSymbolTable(astNode);
               ROSE_ASSERT (symbolTable != NULL);

               bool foundTransformationOptimizationSpecifier = false;

            // printf ("Now print out the information in the symbol table for this scope: \n");
            // symbolTable->print();

#if 0
            // I don't know when a SymbolTable is given a name!
               printf ("SymbolTable has a name = %s \n",
                    (symbolTable->get_no_name()) ? "NO: it has no name" : "YES: it does have a name");
               if (!symbolTable->get_no_name())
                    printf ("SymbolTable name = %s \n",symbolTable->get_name().str());
                 else
                    ROSE_ASSERT (symbolTable->get_name().str() == NULL);
#endif

               if (symbolTable->get_table() != NULL)
                  {
                    SgSymbolTable::hash_iterator i = symbolTable->get_table()->begin();
                    int counter = 0;
                    while (i != symbolTable->get_table()->end())
                       {
                         ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL );

                      // printf ("Initial info: number: %d pair.first (SgName) = %s pair.second (SgSymbol) sage_class_name() = %s \n",
                      //      counter,(*i).first.str(),(*i).second->sage_class_name());

                         SgSymbol* symbol = isSgSymbol((*i).second);
                         ROSE_ASSERT ( symbol != NULL );
                         SgType* type = symbol->get_type();
                         ROSE_ASSERT ( type != NULL );

                         SgNamedType* namedType = isSgNamedType(type);
                         string typeName;
                         if (namedType != NULL)
                            {
                              SgName n = namedType->get_name();
                              typeName = namedType->get_name().str();
                           // char* nameString = namedType->get_name().str();
                           // printf ("Type is: (named type) = %s \n",nameString);
                              ROSE_ASSERT (identifingTypeName.c_str() != NULL);
                           // ROSE_ASSERT (typeName != NULL);
                           // printf ("In getTransformationOptions(): typeName = %s identifingTypeName = %s \n",typeName.c_str(),identifingTypeName.c_str());
                           // if ( (typeName != NULL) && ( typeName == identifingTypeName) )
                              if ( typeName == identifingTypeName )
                                 {
                                // Now look at the parameter list to the constructor and save the
                                // values into the list.

                                // printf ("Now save the constructor arguments! \n");

                                   SgVariableSymbol* variableSymbol = isSgVariableSymbol(symbol);

                                   if ( variableSymbol != NULL )
                                      {
                                        SgInitializedName* initializedNameDeclaration = variableSymbol->get_declaration();
                                        ROSE_ASSERT (initializedNameDeclaration != NULL);

                                        SgDeclarationStatement* declarationStatement = initializedNameDeclaration->get_declaration();
                                        ROSE_ASSERT (declarationStatement != NULL);

                                        SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(declarationStatement);
                                        ROSE_ASSERT (variableDeclaration != NULL);

                                        getTransformationOptionsFromVariableDeclarationConstructorArguments(variableDeclaration,generatedList);

                                        foundTransformationOptimizationSpecifier = true;

                                     // printf ("Exiting after saving the constructor arguments! \n");
                                     // ROSE_ABORT();
                                      }
                                     else
                                      {
#if 0
                                        printf ("Not a SgVariableSymbol: symbol->sage_class_name() = %s \n",
                                             symbol->sage_class_name());
#endif
                                      }
                                 }
                                else
                                 {
#if 0
                                   printf ("typeName != identifingTypeName : symbol->sage_class_name() = %s \n",
                                        symbol->sage_class_name());
#endif
#if 0
                                // I don't think this should ever be NULL (but it is sometimes)
                                   if (typeName != NULL)
                                        printf ("typeName == NULL \n");
#endif
                                 }
                            }
                           else
                            {
                              typeName = (char *)type->sage_class_name();
                            }

                      // printf ("In while loop at the base: counter = %d \n",counter);
                         i++;
                         counter++;
                       }
                  }
                 else
                  {
                 // printf ("Pointer to symbol table is NULL \n");
                  }

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

            // SgSymbolTable objects don't have a parent node (specifically they lack a get_parent
            // member function in the interface)!
               break;
             }

          case BASIC_BLOCK_STMT:
             {
            // List the variable in each scope
            // printf ("List all the variables in this scope! \n");
               SgBasicBlock* basicBlock = isSgBasicBlock(astNode);
               ROSE_ASSERT (basicBlock != NULL);

               SgSymbolTable* symbolTable = basicBlock->get_symbol_table();
               ROSE_ASSERT (symbolTable != NULL);
               getTransformationOptions ( symbolTable, generatedList, identifingTypeName );

            // Next go (fall through this case) to the default case so that we traverse the parent
            // of the SgBasicBlock.
            // break;
             }

          default:
            // Most cases will be the default (this is by design)
            // printf ("default in switch found in globalQueryGetListOperandStringFunction() (sage_class_name = %s) \n",astNode->sage_class_name());

            // Need to recursively backtrack through the parents until we reach the SgGlobal (global scope)
               SgStatement* statement = isSgStatement(astNode);
               if (statement != NULL)
                  {
                    SgNode* parentNode = statement->get_parent();
                    ROSE_ASSERT (parentNode != NULL);
//                  printf ("parent = %p parentNode->sage_class_name() = %s \n",parentNode,parentNode->sage_class_name());
                    SgStatement* parentStatement = isSgStatement(parentNode);
                    if (parentStatement == NULL)
                       {
                         printf ("parentStatement == NULL: statement (%p) is a %s \n",statement,statement->sage_class_name());
                         printf ("parentStatement == NULL: statement->get_file_info()->get_filename() = %s \n",statement->get_file_info()->get_filename());
                         printf ("parentStatement == NULL: statement->get_file_info()->get_line() = %d \n",statement->get_file_info()->get_line());
                       }
                    ROSE_ASSERT (parentStatement != NULL);

                 // Call this function recursively (directly rather than through the query mechanism)
                    getTransformationOptions ( parentStatement, generatedList, identifingTypeName );
                  }
                 else
                  {
                 // printf ("astNode is not a SgStatement! \n");
                  }

               break;
        }

#if 0
     printf ("At BASE of getTransformationOptions(): astNode->sage_class_name() = %s size of generatedList = %d \n",
          astNode->sage_class_name(),generatedList.size());
#endif

  // printf ("######################### END OF TRANSFORMATION OPTION QUERY ######################## \n");
   }
SgNode*
SourceLocationInheritedAttribute::
getCurrentStatementInScope( SgScopeStatement* targetScope ) const
   {
     ROSE_ASSERT (targetScope != NULL);

#if 1
     printf ("At top of SourceLocationInheritedAttribute::getCurrentStatementInScope(): targetScope = %p targetScope->sage_class_name() = %s \n",
          targetScope,targetScope->sage_class_name());
#endif

     int scopeDepth = -1;
     unsigned int i;

  // Search the scopeList for the target scope. We no longer use the index of the 
  // scope to compute the index into the statement list. This would be complicated 
  // since the lists are different sizes debending on the details of the traversal 
  // of the AST (what is a child vs. what is a new sort of Sage node).
     for (i = 0; i < scopeList.size(); i++)
        {
          ROSE_ASSERT (scopeList[i] != NULL);
          if (scopeList[i] == targetScope)
               scopeDepth = i;
        }

#if 1
  // error checking (redundent with assert below, but provides better user interface) 
  // printf ("scopeDepth = %d \n",scopeDepth);
     if (scopeDepth < 0)
        {
       // Report an error since no scope was found
          printf ("ERROR: target scope was not found targetScope = %p targetScope->unparseToString() = %s \n",
               targetScope,targetScope->unparseToString().c_str());
          ROSE_ABORT();
        }
#endif

     ROSE_ASSERT (scopeDepth >= 0);

  // Now get the depth of the associated target statement
  // int targetStatementDepth = scopeDepth+1;
  // increment depends upon number of functions (could be more than one with local class definitions).
  // int targetStatementDepth = scopeDepth+1;

#if 1
     printf ("In SourceLocationInheritedAttribute::getCurrentStatementInScope(): scopeDepth = %d  scopeList.size()     = %zu \n",scopeDepth,scopeList.size());
     printf ("In SourceLocationInheritedAttribute::getCurrentStatementInScope(): scopeDepth = %d  statementList.size() = %zu \n",scopeDepth,statementList.size());
     printf ("##### Find the associated current statement in the target scope: \n");
#endif

  // If this is not a query about the deepest scope then we can find the current statement 
  // in scopeList by looking at the next scope.  Else we have to look at the last statement in the 
  // statement list (to find the current statement in the deepest (currently local) scope).
     SgStatement* targetStatement = NULL;
     if (scopeDepth < (int)(scopeList.size()-1))
        {
          printf ("     use the NEXT statement in the scope list \n");
#if 0
          targetStatement = scopeList[scopeDepth+1];
#else
       // We need to find the target statement in the targe scope, this might not be in the
       // list of scopes since only some scopes are saved to avoid redundent accumulation of 
       // multiple nodes that can represent only a single scope (e.g. functions).  The scope
       // that we store are not always the ones that represent the first node representing 
       // that scope (e.g. functions). But the targetStaement must be initialized to the 
       // statement that appears in the target scope (because the insertion mechanism requires 
       // this).
          int indexOfTargetStatement = -1;
          for (i = 0; i < statementList.size(); i++)
             {
               ROSE_ASSERT (statementList[i] != NULL);
               if (statementList[i] == targetScope)
                    indexOfTargetStatement = i+1;
             }
          ROSE_ASSERT (indexOfTargetStatement >= 0);
          ROSE_ASSERT (indexOfTargetStatement < (int)statementList.size());
          targetStatement = statementList[indexOfTargetStatement];
#endif
        }
       else
        {
          printf ("     use the LAST statement in the statement list \n");
          targetStatement = *(statementList.rbegin());
        }

     ROSE_ASSERT (targetStatement != NULL);

#if 0
     if (isSgScopeStatement( *(statementList.rbegin()) ) != NULL)
          targetStatementDepth = scopeDepth;
       else
          targetStatementDepth = scopeDepth+1;
#endif

#if 1
     printf ("targetScope     = %p targetScope->sage_class_name()     = %s \n",
          targetScope,targetScope->sage_class_name());
     printf ("targetScope = %p targetScope->unparseToString() = %s \n",
          targetScope,targetScope->unparseToString().c_str());
     printf ("targetStatement = %p targetStatement->sage_class_name() = %s \n",
          targetStatement,targetStatement->sage_class_name());
     printf ("targetStatement = %p targetStatement->unparseToString() = %s \n",
          targetStatement,targetStatement->unparseToString().c_str());
#endif

#if ROSE_INTERNAL_DEBUG
  // Error checking: search for targetStatement within the targetScope
     bool found = false;
     if (targetScope->containsOnlyDeclarations() == true)
        {
          printf ("Looking in a scope containing only declarations ... \n");
          SgDeclarationStatementPtrList & declarationList = targetScope->getDeclarationList();
          ROSE_ASSERT (declarationList.size() > 0);
          SgDeclarationStatementPtrList::iterator j;
          for (j = declarationList.begin(); j != declarationList.end(); j++)
             {
               ROSE_ASSERT ((*j) != NULL);
#if 0
               printf ("Testing against declaration: (*j) = %p (*j)->unparseToString() = %s \n",
                    (*j),(*j)->unparseToString().c_str());
#endif
               if ( (*j) == targetStatement )
                    found = true;
             }
        }
       else
        {
          printf ("Looking in a scope containing any statement nodes ... \n");
          SgStatementPtrList & statementList = targetScope->getStatementList();
          ROSE_ASSERT (statementList.size() > 0);
          SgStatementPtrList::iterator j;
          for (j = statementList.begin(); j != statementList.end(); j++)
             {
               ROSE_ASSERT ((*j) != NULL);
#if 0
               printf ("Testing against statement: (*j) = %p (*j)->unparseToString() = %s \n",
                    (*j),(*j)->unparseToString().c_str());
#endif
               if ( (*j) == targetStatement )
                    found = true;
             }
        }

     if (found == false)
          display("At base of SourceLocationInheritedAttribute::getCurrentStatementInScope()");

     ROSE_ASSERT (found == true);
#endif

#if 0
     printf ("Exiting at base of SourceLocationInheritedAttribute::getCurrentStatementInScope() \n");
     ROSE_ABORT();
#endif

     ROSE_ASSERT (targetStatement != NULL);

     return targetStatement;
   }
// Insert a new statement before or after a target statement.  If
// allowForInit is true, the new statement can be inserted into the
// initializer of a for statement.
// Needs to be merged
void myStatementInsert ( SgStatement* target, SgStatement* newstmt, bool before, bool allowForInit )
   {
     ROSE_ASSERT(target != NULL);
     ROSE_ASSERT(newstmt != NULL);
#if 0
     printf ("In inlining: myStatementInsert(): newstmt = %p = %s \n",newstmt,newstmt->class_name().c_str());
     printf ("In inlining: myStatementInsert(): target = %p = %s \n",target,target->class_name().c_str());
#endif
     SgStatement* parent = isSgStatement(target->get_parent());
#if 0
     if (parent == NULL)
        {
          ROSE_ASSERT(target->get_file_info() != NULL);
          target->get_file_info()->display("problem IR node: debug");

          if (target != NULL)
             {
            // printf ("In inlining: myStatementInsert(): target->get_parent() = %p = %s \n",target->get_parent(),target->get_parent()->class_name().c_str());
               printf ("In inlining: myStatementInsert(): target->get_parent() = %p \n",target->get_parent());
             }
        }
#endif
  // cerr << "1: target is a " << target->sage_class_name() << ", target->get_parent() is a " << target->get_parent()->sage_class_name() << endl;
     if (isSgIfStmt(parent) && isSgIfStmt(parent)->get_conditional() == target)
        {
          target = parent;
          parent = isSgScopeStatement(target->get_parent());
        }

  // printf ("allowForInit = %s \n",allowForInit ? "true" : "false");
     if (isSgForInitStatement(target->get_parent()) && !allowForInit)
        {
          target = isSgScopeStatement(target->get_parent()->get_parent());
          parent = isSgScopeStatement(target->get_parent());
          assert (target);
        }

     if (isSgSwitchStatement(target->get_parent()) && target == isSgSwitchStatement(target->get_parent())->get_item_selector()) {
       target = isSgScopeStatement(target->get_parent()->get_parent());
       parent = isSgScopeStatement(target->get_parent());
       assert (target);
     }

     ROSE_ASSERT(target != NULL);
#if 0
  // DQ (8/1/2005): This fails because the parent at some point is not set and the unparseToString detects this (likely in qualifier generation)
     cerr << "2: target is a " << target->sage_class_name() << ", target->get_parent() is a " << target->get_parent()->sage_class_name() << endl;
     ROSE_ASSERT(parent != NULL);
     if (parent->get_parent() == NULL)
        {
          printf ("Found null parent of %p = %s \n",parent,parent->class_name().c_str());
        }
     ROSE_ASSERT(parent->get_parent() != NULL);
     cerr << "2: parent is a " << parent->sage_class_name() << ", parent->get_parent() is a " << parent->get_parent()->sage_class_name() << endl;
  // cerr << "2: target is " << target->unparseToString() << ", target->get_parent() is " << target->get_parent()->unparseToString() << endl;
#endif
     ROSE_ASSERT (parent);
     SgStatementPtrList* siblings_ptr;
     if (isSgForInitStatement(target->get_parent()))
        {
          siblings_ptr = &isSgForInitStatement(target->get_parent())->get_init_stmt();
        }
       else
        {
          assert (parent);
          if (isSgScopeStatement(parent))
             {
               ROSE_ASSERT(parent != NULL);
               siblings_ptr = &isSgScopeStatement(parent)->getStatementList();
               parent = isSgStatement(target->get_parent()); // getStatementList might have changed it when parent was a loop or something similar
               ROSE_ASSERT (parent);
             }
            else
             {
               assert (!"Bad parent type");
             }
        }

     ROSE_ASSERT(siblings_ptr != NULL);
     ROSE_ASSERT(target != NULL);

     SgStatementPtrList& siblings = *siblings_ptr;
     SgStatementPtrList::iterator stmt_iter = std::find(siblings.begin(), siblings.end(), target);
     ROSE_ASSERT (stmt_iter != siblings.end());

     if (!before)
          ++stmt_iter;

     newstmt->set_parent(parent);
     siblings.insert(stmt_iter, newstmt);
   }