Beispiel #1
0
string
IndexOperandDataBase::generateIdentifierString() const
   {
     string returnString;

#if 0
     switch (origin)
        { 
          case unknown: returnString = "unknown";
               break;
          case notStaticlyKnown: returnString = "notStaticlyKnown";
               break;
          case scalarValue: returnString = "scalar0";
               break;
          case baseBoundValues: returnString = "scalar1";
               break;
          case baseBoundStrideValues: returnString = "scalar2";
               break;
          default:
               printf ("Error: default reached in IndexOperandDataBase::generateIdentifierString() \n");
               ROSE_ABORT();
               break;
        }
#else
     returnString = indexVariableName;
#endif

     return returnString;
   }
ProgramTransformationSynthesizedAttributeType
ArrayStatementTraversal::arrayAssignmentTransformation (
    const ProgramTransformationInheritedAttributeType & inheritedAttribute,
    SgNode* astNode )
{
    // The purpose of this transformation is to insert the array transformation in place of each array
    // statement.  This is a function defined in the class derived from the TransformationSpecificationType.
    // This function is a pure virtual function within the TransformationSpecificationType base class.

    // This function requires that the inherited attribute be passed so that we can pass it along to
    // the nested transformation.

    ROSE_ASSERT (astNode != NULL);
    ROSE_ASSERT (isSgExprStatement(astNode) != NULL);

    // This function is at the top level using the SgProject as input (to make the source position mechanism work)
    // ROSE_ASSERT (isSgProject(astNode) != NULL);

    ProgramTransformationSynthesizedAttributeType gatheredInfo(astNode);
    if (ArrayAssignmentStatementTransformation::targetForTransformation(astNode) == true)
    {
        // printf ("Calling ArrayAssignmentStatementTransformation::transformation() \n");
        gatheredInfo = ArrayAssignmentStatementTransformation::transformation ( inheritedAttribute, astNode );
        // printf ("At base of case 'ArrayAssignmentStatementTransformation::targetForTransformation(astNode) == true' \n");

        // gatheredInfo.display("Called from ArrayStatementTraversal::arrayAssignmentTransformation() after ArrayAssignmentStatementTransformation::transformation()");

        // Since the transformation shouldhave generated global variable we can make sure that some strings are present
        ROSE_ASSERT (gatheredInfo.isEmpty() == false);

#if 0
        printf ("Exiting as part of testing ... (at base of ArrayStatementTraversal::arrayAssignmentTransformation) \n");
        ROSE_ABORT();
#endif
    }

    // gatheredInfo.display("Called from ArrayStatementTraversal::arrayAssignmentTransformation()");

#if 0
    printf ("Exiting as part of testing ... (at base of ArrayStatementTraversal::arrayTransformation) \n");
    ROSE_ABORT();
#endif

    // This copies and returns the SynthesizedAttributeBaseClassType information
    return gatheredInfo;
}
ArrayStatementQueryInheritedAttributeType::
ArrayStatementQueryInheritedAttributeType ()
   {
  // This constructor should never be called
     printf ("In ArrayStatementQueryInheritedAttributeType: Base class initialized with NULL pointer \n");
     ROSE_ABORT();

     arrayStatementDimensionDefined = false;
     arrayStatementDimension        = -1;
   }
Beispiel #4
0
void
OperandDataBaseType::
setVariableNameList ( const list<string> & X )
   {
  // This interface is to support the addition of a list of variables into the data base
  // this occurs when we add all the variables represented in a synthesized attribute
  // to a new attribute (as part of the the assemble process).

#if 0
     printf ("In OperandDataBaseType::setVariableNameList(): Now add the information in X to the current database \n");
     printf ("... X names -------------  (list size = %d): %s \n",X.size(),StringUtility::listToString(X).c_str());
  // printf ("... variableNameList names (list size = %d): %s \n",variableNameList.size(),StringUtility::listToString(variableNameList).c_str());
#endif

     bool appendedNewArrayOperand = FALSE;
     list<string>::const_iterator i;
     for (i = X.begin(); i != X.end(); i++)
        {
       // printf ("Looping through variable names \n");
#if 1
       // newer implementation (shorter)
          setVariableName(*i);
#else
          appendedNewArrayOperand = ArrayOperandDataBase::contains(arrayOperandList,*i);

          if ( appendedNewArrayOperand == FALSE )
             {
               printf ("append database info to array operand already present (name = %s) \n",(*i).c_str());
               arrayOperandList.push_back( ArrayOperandDataBase(*i) );
             }
            else
             {
               printf ("Variable already exists (name = %s) \n",(*i).c_str());
             }

          ROSE_ASSERT (arrayOperandList.size() > 0);
#endif
        }

#if 0
  // variableNameList = X;

  // This steals the data out of the X list (X.size() == 0 afterwards)
     variableNameList.merge(X);

     variableNameList.sort();
     variableNameList.unique();
#endif

#if 0
     printf ("Exiting in OperandDataBaseType::setVariableNameList() \n");
     ROSE_ABORT();
#endif
   }
bool isMethodCall(SgFunctionCallExp *functionCall, bool &isDotExp)
{
  ROSE_ASSERT(functionCall != NULL);

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

  bool isMethod = false;
  isDotExp = false;

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

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

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

  return isMethod;
}
// Functions required by the global tree traversal mechanism
ProgramTransformationSynthesizedAttributeType
ArrayStatementTraversal::evaluateRewriteSynthesizedAttribute (
    SgNode* astNode,
    ProgramTransformationInheritedAttributeType inheritedAttribute,
    SubTreeSynthesizedAttributes synthesizedAttributeList)
{
    // Build the synthesizied attribute that this function will return
    ProgramTransformationSynthesizedAttributeType returnSynthesizedAttribute(astNode);

#if 0
    printf ("$$$$$ TOP of ArrayStatementTraversal::evaluateRewriteSynthesizedAttribute (astNode = %s) (synthesizedAttributeList.size() = %d) \n",
            astNode->sage_class_name(),synthesizedAttributeList.size());
    // inheritedAttribute.display("In ArrayStatementTraversal::evaluateRewriteInheritedAttribute");
#endif

    if (astNode->variantT() == V_SgExprStatement)
    {
        // The program logic can't reset the returnSynthesizedAttribute for each transformation
#if 0
        printf ("ERROR: In ArrayStatementTraversal::evaluateRewriteSynthesizedAttribute(): The program logic can't reset the returnSynthesizedAttribute for each transformation... \n");
        ROSE_ABORT();
#endif

        // printf ("Found an expression statement (programTransformation.C) \n");

        // We use the operator+=() because more than one transformation function could be called in general.
        // Below we will call the scalar indexing transformation as a second transformation.  Both, and more,
        // will be called for Expression statements in the future (e.g. indirect addressing).
        // returnSynthesizedAttribute += arrayAssignmentTransformation(inheritedAttribute,astNode);
#if 0
        // printf ("Calling arrayAssignmentTransformation() \n");
        returnSynthesizedAttribute = arrayAssignmentTransformation(inheritedAttribute,astNode);
        // arrayAssignmentTransformation(inheritedAttribute,astNode);
        // printf ("DONE: arrayAssignmentTransformation() \n");
#endif

#if 1
        // Turn off the scalar indexing transformation for now
        // returnSynthesizedAttribute += ScalarIndexingArrayStatementTransformation::transformation(project,astNode);
        // returnSynthesizedAttribute += ScalarIndexingArrayStatementTransformation::transformation(inheritedAttribute,astNode);
        returnSynthesizedAttribute = arrayScalarIndexingTransformation(inheritedAttribute,astNode);
#endif
    }

#if 0
    printf ("$$$$$ BOTTOM of attributeAssemblyFunction (astNode = %s) (declaration list size = %d) (returnSynthesizedAttribute.getTransformationSourceCode() = \n%s) \n",
            astNode->sage_class_name(),
            returnSynthesizedAttribute.variableDeclarationList.size(),
            returnSynthesizedAttribute.getSourceCodeString().c_str());
#endif

    return returnSynthesizedAttribute;
}
ProgramTransformationSynthesizedAttributeType
ArrayStatementTraversal::arrayScalarIndexingTransformation (
    const ProgramTransformationInheritedAttributeType & inheritedAttribute,
    SgNode* astNode )
{
    ROSE_ASSERT (astNode != NULL);
    ROSE_ASSERT (isSgExprStatement(astNode) != NULL);

    ProgramTransformationSynthesizedAttributeType gatheredInfo(astNode);
    if (ScalarIndexingStatementTransformation::targetForTransformation(astNode) == true)
    {
        // printf ("Calling ScalarIndexingArrayStatementTransformation::transformation() \n");
        gatheredInfo = ScalarIndexingStatementTransformation::transformation(inheritedAttribute,astNode);
        // printf ("At base of case 'ScalarIndexingArrayStatementTransformation::targetForTransformation(astNode) == true' \n");

        // gatheredInfo.display("Called from ArrayStatementTraversal::arrayAssignmentTransformation() after ArrayAssignmentStatementTransformation::transformation()");

        // Since the transformation shouldhave generated global variable we can make sure that some strings are present
        ROSE_ASSERT (gatheredInfo.isEmpty() == false);

#if 0
        printf ("Exiting as part of testing ... (at base of ArrayStatementTraversal::arrayScalarIndexingTransformation) \n");
        ROSE_ABORT();
#endif
    }

    // gatheredInfo.display("Called from ArrayStatementTraversal::arrayScalarIndexingTransformation()");

#if 0
    printf ("Exiting as part of testing ... (at base of ArrayStatementTraversal::arrayScalarIndexingTransformation) \n");
    ROSE_ABORT();
#endif

    // This copies and returns the SynthesizedAttributeBaseClassType information
    return gatheredInfo;
}
Beispiel #8
0
void
IndexOperandDataBase::merge( vector<IndexOperandDataBase> & X, const vector<IndexOperandDataBase> & Y )
   {
  // traverse Y and add elements to X if they represent new operands

  // printf ("In IndexOperandDataBase::merge(X,Y): merging list Y into list X \n");
  // printf ("In IndexOperandDataBase::merge(X,Y): X.size() = %d  Y.size() = %d \n",X.size(),Y.size());

     vector<IndexOperandDataBase> listOfIndexOperandsToAdd;
     vector<IndexOperandDataBase>::const_iterator i;
     for (i = Y.begin(); i != Y.end(); i++)
        {
       // printf ("Iterating through array operands in Y (*i).displayString() = %s \n",(*i).displayString().c_str());
          vector<IndexOperandDataBase>::iterator j;
          for (j = X.begin(); j != X.end(); j++)
             {
            // printf ("Iterating through array operands in X (*j).displayString() = %s \n",(*j).displayString().c_str());
               if (*j == *i)
                  {
                 // printf ("Processing index operand: calling (*j).merge(*i) \n");
                    (*j).merge(*i);
                  }
                 else
                  {
                 // printf ("Processing index operand: calling X.push_back(*i) \n");
                    X.push_back(*i);
                  }
             }
        }

  // Now add the identified index operands to the X list     
     vector<IndexOperandDataBase>::iterator k;
     for (k = listOfIndexOperandsToAdd.begin(); k != listOfIndexOperandsToAdd.end(); k++)
        {
       // printf ("Adding identified index operand to X list: (*k).displayString() = %s \n",(*k).displayString().c_str());
          X.push_back(*k);
        }

  // IndexOperandDataBase::merge( X, Y );
#if 0
     printf ("Exiting in IndexOperandDataBase::merge() \n");
     ROSE_ABORT();
#endif
   }
Beispiel #9
0
       string typeStringFromType(SgType* sageType){
	          ROSE_ASSERT( sageType != NULL );
              vector<SgType*> typeVector = typeVectorFromType(sageType); 

		      string typeParsed = "";
		      for(int i = typeVector.size()-1; i>=0; i=i-1){
		        sageType = typeVector[i];

		    	switch(sageType->variantT())
			      {
				   case V_SgReferenceType: 
					break;
	               case V_SgPointerType:
				 	typeParsed = typeParsed + "*";	
	                break;
                   case V_SgTypedefType:
                    ROSE_ABORT();
			       default:
					typeParsed = typeParsed + TransformationSupport::getTypeName(sageType);
					break;
			};	
		  }
		  return typeParsed;
       };
// ScalarIndexingStatementQuerySynthesizedAttributeType
SynthesizedAttributeBaseClassType
ScalarIndexingStatementTransformation::transformation
   ( const ArrayStatementQueryInheritedAttributeType & X, SgNode* astNode )
   {
  // This function returns the string representing the array statement transformation
     ROSE_ASSERT (isSgExprStatement(astNode) != NULL);

     ScalarIndexingStatementQueryInheritedAttributeType scalarIndexingStatementQueryInheritedData(X,astNode);

  // Declare the list to place transformation options into from each scope as we traverse backward
  // (up) the AST to the Global scope.
  // list<int> transformationOptions; // inherited attribute
     list<int> & transformationOptions = scalarIndexingStatementQueryInheritedData.getTransformationOptions();

     printf ("ScalarIndexingStatementQueryInheritedData.arrayStatementDimension = %d \n",
          scalarIndexingStatementQueryInheritedData.arrayStatementDimension);

  // We have to use a special function here instead of the Query mechanism since the Query mechanism
  // searches down through he AST (parents traverse their children) and we want to traverse up
  // through the AST (and not the whole AST) from the child to the parent stopping at the root of
  // the AST (the global scope: SgGlobal)
     printf ("############### CALLING TRANSFORMATION OPTION QUERY FROM ASSIGNMENT TRANSFORMATION ############ \n");

  // Find all the hints specified as enum values constructor parameters for declarations of
  // variables of type "TransformationAssertion".  The current scope and all parent scopes are
  // searched back to the global scope. (Maybe this should return a value rather than modify a
  // reference parameter???)
     TransformationSupport::getTransformationOptions ( astNode, transformationOptions, "TransformationAssertion");

#if 1
  // List the different transformation options that are specified in the user's code
  // list<TransformationAssertion::TransformationOption>::iterator transformationOptionListIterator;
     list<int>::iterator transformationOptionListIterator;
     for (transformationOptionListIterator  = transformationOptions.begin();
          transformationOptionListIterator != transformationOptions.end();
          transformationOptionListIterator++)
        {
       // display each value
       // TransformationAssertion::TransformationOption i = *transformationOptionListIterator;
          int i = *transformationOptionListIterator;
          printf ("     Value in transformation option = %d name = %s \n",i,TransformationAssertion::getOptionString(i));
        }
#endif

  // If there are any index object in use then we can't do the transformation (so make sure there are none)
     ROSE_ASSERT (NameQuery::getVariableNamesWithTypeNameQuery (astNode,"Internal_Index").size() == 0);

     printf ("######################### END OF INTERNALINDEX NAME QUERY ######################## \n");

     printf ("################# START OF ARRAY STATEMENT DIMENSION QUERY ################ \n");

  // The dimension of the array statement must be computed on the way down (in the traversal of the AST).
  // This query gets the list of integer associated with the dimension of each array operand (array
  // operands using the doubleArray::operator() member function).
     list<int> operandDimensionList =
          NumberQuery::getNumberOfArgumentsToParenthesisOperatorQuery (astNode, "doubleArray" );
     ROSE_ASSERT (operandDimensionList.size() >= 0);

#if 1
     printf ("operandDimensionList.size() = %d \n",operandDimensionList.size());
     printf ("operandDimensionList = \n%s\n",StringUtility::listToString(operandDimensionList).c_str());
#endif

  // Now use STL to build a list of unique names
     operandDimensionList.unique();
#if 0
     printf ("Unique Names: operandDimensionList = \n%s\n",StringUtility::listToString(operandDimensionList).c_str());
#endif

  // If there is no dimension computed for the query then it means that there were no operator()
  // used in which case we have to assume 6D array operations
     int dimensionOfArrayStatement = (operandDimensionList.size() == 0) ? 6 : *(operandDimensionList.begin());
     printf ("Array statement is %d dimensional \n",dimensionOfArrayStatement);

  // Make sure that it has the default value before we change it (error checking)
     printf ("ScalarIndexingStatementQueryInheritedData.arrayStatementDimension = %d \n",
          scalarIndexingStatementQueryInheritedData.arrayStatementDimension);
     ROSE_ASSERT (scalarIndexingStatementQueryInheritedData.arrayStatementDimension == -1);

  // Modify the inherited attribute using the array statement dimension data
     scalarIndexingStatementQueryInheritedData.arrayStatementDimensionDefined = TRUE;
     scalarIndexingStatementQueryInheritedData.arrayStatementDimension        = dimensionOfArrayStatement;

#if 0
     printf ("ScalarIndexingStatementQueryInheritedData.arrayStatementDimension = %d \n",
          scalarIndexingStatementQueryInheritedData.arrayStatementDimension);
     printf ("Exiting as part of testing (after search for array statement dimension) ... \n");
     ROSE_ABORT();
#endif

     ScalarIndexingStatementTransformation transformation;

  // Build a return value for this function
     ScalarIndexingStatementQuerySynthesizedAttributeType returnScalarIndexingStatementTransformation(astNode);

  // We need these until we have a new interface which will allow us to skip them (they are not used)
  // ScalarIndexingStatementQueryAccumulatorType        accumulatorValue;

  // WARNING: It is a design problem that we have the dimension set in two locations

  // To to implement this transformation withouth a database mechanism
  // Set the dimension of the array statement in the array operand database
     transformation.accumulatorValue.operandDataBase.setDimension(dimensionOfArrayStatement);
     ROSE_ASSERT (transformation.accumulatorValue.operandDataBase.getDimension() > 0);

  // Setup the data base with the options specified by the use and extracted from the current scope
  // of the application code.
     transformation.accumulatorValue.operandDataBase.setUserOptimizationAssertions
          (scalarIndexingStatementQueryInheritedData.transformationOptions);
     ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.transformationOption > 
                   ArrayTransformationSupport::UnknownIndexingAccess );

  // Make sure the data base has been setup properly
     ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.transformationOption >
          ArrayTransformationSupport::UnknownIndexingAccess );
     ROSE_ASSERT ( transformation.accumulatorValue.operandDataBase.dimension > -1 );

  // We must call this preorder because we modify the inherited attribute on the way down into the
  // AST so that the assembly will have the correct array statment dimension on the way back up (the
  // assembly of attributes always happens postorder).
     returnScalarIndexingStatementTransformation =
          transformation.traverse ( astNode, scalarIndexingStatementQueryInheritedData );

  // printf ("accumulatorValue.operandDataBase.displayString() = %s \n",accumulatorValue.operandDataBase.displayString().c_str());
  // ROSE_ASSERT (accumulatorValue.operandDataBase.size() > 0);

  // Copy the operand data base out of the accumulator attribute and into the ScalarIndexingStatementTransformation object
  // operandDataBase = transformation.accumulatorValue.operandDataBase;

  // printf ("transformation.accumulatorValue.operandDataBase.displayString() = %s \n",
  //      transformation.accumulatorValue.operandDataBase.displayString().c_str());

#if 0
  // Verify that we have saved the global and variable declarations and variable initializations
     ROSE_ASSERT (returnScalarIndexingStatementTransformation.globalDeclarationStrings.isEmpty()      == false);
     ROSE_ASSERT (returnScalarIndexingStatementTransformation.variableDeclarationStrings.isEmpty()    == false);
     ROSE_ASSERT (returnScalarIndexingStatementTransformation.variableInitializationStrings.isEmpty() == false);
#endif

  // Verify that we have a valid string
     ROSE_ASSERT (returnScalarIndexingStatementTransformation.isEmpty() == false);

     printf ("######################### END OF SCALAR INDEXING TRANSFORMATION QUERY ######################## \n");

     printf ("returnScalarIndexingStatementTransformation.getTransformationSourceCode().c_str() = \n%s \n",
          returnScalarIndexingStatementTransformation.getWorkSpace().c_str());

#if 0
  // NOTE: I think we need to get the variable declarations out of returnArrayStatementTransformation
     list<string> stringList = returnArrayStatementTransformation.getVariableDeclarationStrings();
     ROSE_ASSERT (stringList.size() > 0);
     for (list<string>::iterator i = stringList.begin(); i != stringList.end(); i++)
          printf ("Base of ScalarIndexingStatementTransformation::transformation(): getVariableDeclarationStrings() = %s \n",(*i).c_str());
#endif

#if 0
     printf ("Exiting as part of testing (after SCALAR INDEXING TRANSFORMATION QUERY) ... \n");
     ROSE_ABORT();
#endif

     return returnScalarIndexingStatementTransformation;
   }
int
main ( int argc, char* argv[] )
   {
  // Main Function for default example ROSE Preprocessor
  // This is an example of a preprocessor that can be built with ROSE
  // This example can be used to test the ROSE infrastructure

#if 1
     list<string> l = CommandlineProcessing::generateArgListFromArgcArgv (argc,argv);
     printf ("Preprocessor (before): argv = \n%s \n",StringUtility::listToString(l).c_str());

  // testing removeArgs
     CommandlineProcessing::removeArgs (argc,argv,"-edg:");
     CommandlineProcessing::removeArgs (argc,argv,"--edg:");
     CommandlineProcessing::removeArgsWithParameters (argc,argv,"-edg_parameter:");
     CommandlineProcessing::removeArgsWithParameters (argc,argv,"--edg_parameter:");

     printf ("argc = %d \n",argc);
     l = CommandlineProcessing::generateArgListFromArgcArgv (argc,argv);
     printf ("l.size() = %d \n",l.size());
     printf ("Preprocessor (after): argv = \n%s \n",StringUtility::listToString(l).c_str());

  // printf ("Exiting in main! \n");
  // ROSE_ASSERT(1 == 2);
#endif

#if 0
     int modifiedArgc    = 0;
     char** modifiedArgv = NULL;

  // resets modifiedArgc and allocates memory to modifiedArgv
  // list<string> edgOptionWithNameParameterList = 
  //      CommandlineProcessing::generateOptionWithNameParameterList (argc, argv,"-edg_parameter:",modifiedArgc,modifiedArgv);

  // resets modifiedArgc and allocates memory to modifiedArgv
     list<string> edgOptionWithNumberParameterList =
          CommandlineProcessing::generateOptionWithNameParameterList (argc, argv,"-edg_parameter:",modifiedArgc,modifiedArgv);

     l = CommandlineProcessing::generateArgListFromArgcArgv (modifiedArgc,modifiedArgv);
     printf ("Preprocessor (after): argv = \n%s \n",StringUtility::listToString(l).c_str());

  // resets modifiedArgc to zero and releases memory from modifiedArgv (resets modifiedArgv to NULL)
     CommandlineProcessing::releaseArgListMemory(modifiedArgc,modifiedArgv);
#endif

#if 0
     if ( CommandlineProcessing::isOption(argc,argv,"-rose:","(h|help)",true) ||
          CommandlineProcessing::isOption(argc,argv,"-", "(h|help)",true) ||
          CommandlineProcessing::isOption(argc,argv,"--","(h|help)",true) )
        {
          printf ("\nROSE (pre-release alpha version: %s) \n",VERSION);
          ROSE::usage(0);
          exit(0);
        }

     l = CommandlineProcessing::generateArgListFromArgcArgv (argc,argv);
     printf ("Preprocessor (after): argv = \n%s \n",StringUtility::listToString(l).c_str());

     printf ("Exiting after initial command line processing \n");
     ROSE_ABORT();
#endif

#if 0
     string stringParameter;
     if ( CommandlineProcessing::isOptionWithParameter(argc,argv,"-rose:","(o|output)",stringParameter,true) )
        {
          printf ("-rose:output %s \n",stringParameter.c_str());
       // Make our own copy of the filename string
          int length = stringParameter.length();
          char* p_unparse_output_filename = (char*) new char[length+1];
          ROSE_ASSERT (p_unparse_output_filename != NULL);
          stringParameter.copy(p_unparse_output_filename,length,0);
          p_unparse_output_filename[length] = '\0';
          printf ("p_unparse_output_filename = %s \n",p_unparse_output_filename);
        }
       else
        {
          printf ("-rose:output not set! \n");
        }
#endif


#if 0
     int modifiedArgc    = 0;
     char** modifiedArgv = NULL;

  // resets modifiedArgc and allocates memory to modifiedArgv
     list<string> edgOptionList = CommandlineProcessing::generateOptionList (argc, argv,"-edg:",modifiedArgc,modifiedArgv);

  // resets modifiedArgc to zero and releases memory from modifiedArgv (resets modifiedArgv to NULL)
     CommandlineProcessing::releaseArgListMemory(modifiedArgc,modifiedArgv);

     if ( CommandlineProcessing::isOption(argc,argv,"-","help",true) )
        {
          printf ("Option -help found! \n");
        }

     if ( CommandlineProcessing::isOption(argc,argv,"--","help",true) )
        {
          printf ("Option --help found! \n");
        }

     int integerParameter;
     if ( CommandlineProcessing::isOptionWithParameter(argc,argv,"-edg:","test",integerParameter,true) )
        {
          printf ("Option (integer parameter) -test %d found! \n",integerParameter);
        }

     string stringParameter;
     if ( CommandlineProcessing::isOptionWithParameter(argc,argv,"-edg:","test",stringParameter,true) )
        {
          printf ("Option (string parameter) -test %s found! \n",stringParameter.c_str());
        }
#endif

     SgProject* project = frontend(argc,argv);
     ROSE_ASSERT (project != NULL);

#if 0
  // See if we can access the EDG AST directly
     ROSE_ASSERT (il_header.primary_source_file != NULL);
     ROSE_ASSERT (il_header.primary_source_file->file_name != NULL);
     printf ("##### il_header.primary_source_file->file_name = %s \n",il_header.primary_source_file->file_name);
#endif

  // DQ (2/6/2004): These tests fail in Coco for test2004_14.C
  // AstTests::runAllTests(const_cast<SgProject*>(project));

  // printf ("Generate the pdf output of the SAGE III AST \n");
  // generatePDF ( project );

     printf ("Generate the DOT output of the SAGE III AST \n");
     generateDOT ( *project );

     return backend(project);

  // alternative form
  // return backend(frontend(argc,argv));
   }
Beispiel #12
0
void
SgNode::insertSourceCode ( SgProject & project,
                           const char* sourceCodeString,
                           const char* localDeclaration,
                           const char* globalDeclaration,
                           bool locateNewCodeAtTop,
                           bool isADeclaration )
   {
  // If this function is useful only for SgBasicBlock then it should be put into that class directly.
  // This function is used to insert code into AST object for which insertion make sense:
  // (specifically any BASIC_BLOCK_STMT)

     if (variant() != BASIC_BLOCK_STMT)
        {
          printf ("ERROR: insert only make since for BASIC_BLOCK_STMT statements (variant() == variant()) \n");
          ROSE_ABORT();
        }

     SgBasicBlock* currentBlock = isSgBasicBlock(this);
     ROSE_ASSERT (currentBlock != NULL);

  // printf ("##### Calling SgNode::generateAST() \n");

#if 0
     printf ("In insertSourceCode(): globalDeclaration = \n%s\n",globalDeclaration);
     printf ("In insertSourceCode(): localDeclaration  = \n%s\n",localDeclaration);
     printf ("In insertSourceCode(): sourceCodeString  = \n%s\n",sourceCodeString);
#endif

  // SgNode* newTransformationAST = generateAST (project,sourceCodeString,globalDeclaration);
  // ROSE_ASSERT (newTransformationAST != NULL);
     SgStatementPtrList* newTransformationStatementListPtr =
          generateAST (project,sourceCodeString,localDeclaration,globalDeclaration,isADeclaration);
     ROSE_ASSERT (newTransformationStatementListPtr != NULL);
     ROSE_ASSERT (newTransformationStatementListPtr->size() > 0);

  // printf ("##### DONE: Calling SgNode::generateAST() \n");

  // get a reference to the statement list out of the basic block
     SgStatementPtrList & currentStatementList = currentBlock->get_statements();

     if (locateNewCodeAtTop == true)
        {
       // Insert at top of list (pull the elements off the bottom of the new statement list to get the order correct
       // printf ("Insert new statements (new statement list size = %d) at the top of the block (in reverse order to preset the order in the final block) \n",newTransformationStatementListPtr->size());
          SgStatementPtrList::reverse_iterator transformationStatementIterator;
          for (transformationStatementIterator = newTransformationStatementListPtr->rbegin();
               transformationStatementIterator != newTransformationStatementListPtr->rend();
               transformationStatementIterator++)
             {
            // Modify where a statement is inserted to avoid dependent variables from being inserted
            // before they are declared.

            // Get a list of the variables
            // Generate the list of types used within the target subtree of the AST
               list<string> typeNameStringList = NameQuery::getTypeNamesQuery ( *transformationStatementIterator );

               int statementCounter         = 0;
               int previousStatementCounter = 0;

            // Declaration furthest in source sequence of all variables referenced in code to be inserted (last in source sequence order)
//             SgStatementPtrList::iterator furthestDeclarationInSourceSequence = NULL;
               SgStatementPtrList::iterator furthestDeclarationInSourceSequence;

#if 0
               string unparsedDeclarationCodeString = (*transformationStatementIterator)->unparseToString();
               ROSE_ASSERT (unparsedDeclarationCodeString.c_str() != NULL);
               printf ("unparsedDeclarationCodeString = %s \n",unparsedDeclarationCodeString.c_str());
#endif
               if ( typeNameStringList.size() > 0 )
                  {
                 // There should be at least one type in the statement
                    ROSE_ASSERT (typeNameStringList.size() > 0);
                 // printf ("typeNameStringList.size() = %d \n",typeNameStringList.size());

                 // printf ("This statement has a dependence upon a variable of some type \n");

                 // Loop over all the types and get list of variables of each type
                 // (so they can be declared properly when the transformation is compiled)
                    list<string>::iterator typeListStringElementIterator;
                    for (typeListStringElementIterator = typeNameStringList.begin();
                         typeListStringElementIterator != typeNameStringList.end();
                         typeListStringElementIterator++)
                       {
                      // printf ("Type = %s \n",(*typeListStringElementIterator).c_str());

                      // Find a list of names of variable of type (*listStringElementIterator)
                         list<string> operandNameStringList =
                              NameQuery::getVariableNamesWithTypeNameQuery
                                 ( *transformationStatementIterator, *typeListStringElementIterator );

                      // There should be at least one variable of that type in the statement
                         ROSE_ASSERT (operandNameStringList.size() > 0);
                      // printf ("operandNameStringList.size() = %d \n",operandNameStringList.size());

                      // Loop over all the types and get list of variable of each type
                         list<string>::iterator variableListStringElementIterator;
                         for (variableListStringElementIterator = operandNameStringList.begin();
                              variableListStringElementIterator != operandNameStringList.end();
                              variableListStringElementIterator++)
                            {
#if 0
                              printf ("Type = %s Variable = %s \n",
                                   (*typeListStringElementIterator).c_str(),
                                   (*variableListStringElementIterator).c_str());
#endif
                              string variableName = *variableListStringElementIterator;
                              string typeName     = *typeListStringElementIterator;

                              SgName name = variableName.c_str();
                              SgVariableSymbol* symbol = currentBlock->lookup_var_symbol(name);
                              if ( symbol != NULL )
                                 {
                                // found a variable with name -- make sure that the declarations 
                                // represented by *transformationStatementIterator are inserted 
                                // after their declaration.
#if 0
                                   printf ("Found a valid symbol corresponding to Type = %s Variable = %s (must be defined in the local scope) \n",
                                        (*typeListStringElementIterator).c_str(),
                                        (*variableListStringElementIterator).c_str());
#endif
                                   ROSE_ASSERT (symbol != NULL);
                                   SgInitializedName* declarationInitializedName = symbol->get_declaration();
                                   ROSE_ASSERT (declarationInitializedName != NULL);
                                   SgDeclarationStatement* declarationStatement  =
                                        declarationInitializedName->get_declaration();
                                   ROSE_ASSERT (declarationStatement != NULL);
#if 0
                                   printf ("declarationStatementString located at line = %d of file = %s \n",
                                        rose::getLineNumber(declarationStatement),
                                        rose::getFileName(declarationStatement));
                                   string declarationStatementString = declarationStatement->unparseToString();
                                   printf ("declarationStatementString = %s \n",declarationStatementString.c_str());
#endif
                                   statementCounter = 1;

                                   SgStatementPtrList::iterator i = currentStatementList.begin();
                                   bool declarationFound = false;
                                   while ( ( i != currentStatementList.end() ) && ( declarationFound == false ) )
                                      {
                                     // searching for the declarationStatement
#if 0
                                        printf ("statementCounter = %d previousStatementCounter = %d \n",
                                             statementCounter,previousStatementCounter);
                                        string currentStatementString = (*i)->unparseToString();
                                        printf ("currentStatementString = %s \n",currentStatementString.c_str());
#endif
                                        if ( (*i == declarationStatement) &&
                                             (statementCounter > previousStatementCounter) )
                                           {
                                          // printf ("Found the declarationStatement at position (statementCounter = %d previousStatementCounter = %d) \n",statementCounter,previousStatementCounter);
                                             declarationFound = true;
                                           }
                                          else
                                           {
                                          // printf ("Not the declaration we are looking for! \n");
                                             i++;
                                             statementCounter++;
                                           }
                                      }

                                // Save a reference to the variable declaration that is furthest in
                                // the source sequence so that we can append the new statement just
                                // after it (so that variables referenced in the new statement will
                                // be defined).
                                   if ( (statementCounter > previousStatementCounter) && ( declarationFound == true ) )
                                      {
                                        previousStatementCounter = statementCounter;
                                        furthestDeclarationInSourceSequence = i;
                                      }
#if 0
                                   printf ("AFTER LOOP OVER STATEMENTS: previousStatementCounter = %d \n",previousStatementCounter);
                                   string lastStatementString = (*furthestDeclarationInSourceSequence)->unparseToString();
                                   printf ("lastStatementString = %s \n",lastStatementString.c_str());
#endif
                                 }
                                else
                                 {
                                // If the variable is not found then insert the new statement at the front of the list
#if 0
                                   printf ("Can NOT find a valid symbol corresponding to Type = %s Variable = %s (so it is not declared in the local scope) \n",
                                        (*typeListStringElementIterator).c_str(),
                                        (*variableListStringElementIterator).c_str());
#endif
                                // currentStatementList.push_front(*transformationStatementIterator);
                                 }
#if 0
                              printf ("BOTTOM OF LOOP OVER VARIABLES: previousStatementCounter = %d \n",previousStatementCounter);
#endif
                            }

                         if (statementCounter > previousStatementCounter)
                              previousStatementCounter = statementCounter;

#if 0
                         printf ("BOTTOM OF LOOP OVER TYPES: previousStatementCounter = %d \n",previousStatementCounter);
#endif
#if 0
                         printf ("Exiting in insertSourceCode(): transformationStatementIterator loop (type = %s) ... \n",(*typeListStringElementIterator).c_str());
                         ROSE_ABORT();
#endif
                       }

#if 0
                    printf ("Exiting in loop insertSourceCode (type = %s) ... \n",(*typeListStringElementIterator).c_str());
                    ROSE_ABORT();
#endif
                 // Now append the new statement AFTER the declaration that we have found
                 // currentStatementList.insert(*targetDeclarationStatementIterator,*transformationStatementIterator);
                 // currentStatementList.insert(lastStatementIterator,*transformationStatementIterator);
#if 1
                 // printf ("BEFORE ADDING NEW STATEMENT: previousStatementCounter = %d \n",previousStatementCounter);
                    if (previousStatementCounter == 0)
                       {
                         printf ("##### Prepend new statement to the top of the local scope \n");
                      // currentStatementList.push_front(*transformationStatementIterator);
                         currentBlock->prepend_statement (*transformationStatementIterator);
                       }
                      else
                       {
                      // printf ("##### Append the new statement after the last position where a dependent variable is declared in the local scope \n");
                      // Use new function added to append/prepend at a specified location in the list of statements
                         currentBlock->append_statement (furthestDeclarationInSourceSequence,*transformationStatementIterator);
                       }
#else
                    SgStatementPtrList::iterator tempIterator = furthestDeclarationInSourceSequence;
                    tempIterator++;
                 // Handle the case of appending at the end of the list
                    if ( tempIterator == currentStatementList.end() )
                       {
                         currentBlock->append_statement (*transformationStatementIterator);
                       }
                      else
                       {
                         currentBlock->insert_statement (tempIterator,*transformationStatementIterator);
                       }
#endif
                  }
                 else
                  {
                 // This statement has no type information (so it has no dependence upon any non-primative type)
                 // "int x;" would be an example of a statement that would not generate a type (though perhaps it should?)
                 // printf ("This statement has no type information (so it has no dependence upon any non-primative type) \n");

                 // So this statment can be places at the front of the list of statements in this block
                 // *** Note that we can't use the STL function directly since it does not set the parent information ***
                 // currentStatementList.push_front(*transformationStatementIterator);
                    currentBlock->insert_statement (currentStatementList.begin(),*transformationStatementIterator);
                  }

#if 0
               string bottomUnparsedDeclarationCodeString = (*transformationStatementIterator)->unparseToString();
               ROSE_ASSERT (bottomUnparsedDeclarationCodeString.c_str() != NULL);
               printf ("bottomUnparsedDeclarationCodeString = %s \n",bottomUnparsedDeclarationCodeString.c_str());
#endif
             }

#if 0
          printf ("Exiting in insertSourceCode(): case of locateNewCodeAtTop == true ... \n");
          ROSE_ABORT();
#endif
        }
       else
        {
       // Put the new statements at the end of the list (traverse the new statements from first to last)
       // But put it before any return statement! So find the last statement!
          SgStatementPtrList::iterator lastStatement = currentStatementList.begin();
          bool foundEndOfList = false;
          while ( (foundEndOfList == false) && (lastStatement != currentStatementList.end()) )
             {
               SgStatementPtrList::iterator tempStatement = lastStatement;
               tempStatement++;
               if (tempStatement == currentStatementList.end())
                    foundEndOfList = true;
                 else
                    lastStatement++;
             }
          ROSE_ASSERT ( *lastStatement != NULL );

       // printf ("(*lastStatement)->sage_class_name() = %s \n",(*lastStatement)->sage_class_name());

       // printf ("Insert new statements at the bottom of the block \n");
          SgStatementPtrList::iterator transformationStatementIterator;
          for (transformationStatementIterator = newTransformationStatementListPtr->begin();
               transformationStatementIterator != newTransformationStatementListPtr->end();
               transformationStatementIterator++)
             {
            // If there is a RETURN_STMT in the block then insert the new statement just before the
            // existing RETURN_STMT
               if ( (*lastStatement)->variant() == RETURN_STMT)
                  {
                 // printf ("Backing away from the end of the list to find the last non-return statement \n");
                 // lastStatement--;
                    currentBlock->insert_statement(lastStatement,*transformationStatementIterator);
                  }
                 else
                  {
                    currentStatementList.push_back(*transformationStatementIterator);
                  }
             }
        }

  // printf ("$CLASSNAME::insertSourceCode taking (SgProject,char*,char*) not implemented yet! \n");
  // ROSE_ABORT();
   }
string
AST_Rewrite::AccumulatedDeclarationsAttribute::
generateDeclarationString ( SgDeclarationStatement* declaration ) const
   {
  // This function generates a string for a declaration. The string is required for 
  // the intermediate file to make sure that all transformation code will compile 
  // (since it could depend on declarations defined within the code).

  // Details:
  //   1) Only record declarations found within the source file (exclude all header files 
  //      since they will be seen when the same header files are included).
  //   2) Resort the variable declarations to remove redundent entries.
  //        WRONG: variable declarations could have dependences upon class declarations!
  //   3) Don't sort all declarations since some could have dependences.
  //        a) class declarations
  //        b) typedefs
  //        c) function declarations
  //        d) template declarations
  //        e) variable definition???

      ROSE_ASSERT (this != NULL);
      ROSE_ASSERT ( declaration != NULL );
      string declarationString;

   // Build a SgUnparse_Info object to represent formatting options for
   // this statement (use the default values).
      SgUnparse_Info info;

   // exclude comments
      info.set_SkipComments();

   // exclude all CPP directives (since they have already been evaluated by the front-end)
      info.set_SkipCPPDirectives();

      switch ( declaration->variantT() )
        {
       // Enum declarations should not skip their definition since 
       // this is where the constants are declared.
          case V_SgEnumDeclaration:

          case V_SgVariableDeclaration:
          case V_SgTemplateDeclaration:
          case V_SgTypedefDeclaration:
            // Need to figure out if a forward declaration would work or be 
            // more conservative and always output the complete class definition.

            // turn off output of initializer values
               info.set_SkipInitializer();
            // output the declaration as a string
               declarationString = globalUnparseToString(declaration,&info);
               break;

          case V_SgClassDeclaration:
            // Need to figure out if a forward declaration would work or be 
            // more conservative and always output the complete class definition.

            // turn off the generation of the function definitions only 
            // (we still want the restof the class definition since these 
            // define all member data and member functions).
            // info.set_SkipClassDefinition();
               info.set_SkipFunctionDefinition();
               info.set_AddSemiColonAfterDeclaration();

            // output the declaration as a string
               declarationString = globalUnparseToString(declaration,&info);
               break;

       // For functions just output the declaration and skip the definition
       // (This also avoids the generation of redundent definitions since the 
       // function we are in when we generate all declarations would be included).
          case V_SgMemberFunctionDeclaration:
          case V_SgFunctionDeclaration:
             {
            // turn off the generation of the definition
               info.set_SkipFunctionDefinition();
               info.set_AddSemiColonAfterDeclaration();

            // output the declaration as a string
               declarationString = globalUnparseToString(declaration,&info);
               break;
             }

          case V_SgFunctionParameterList:
             {
            // Handle generation of declaration strings this case differnetly from unparser
            // since want to generate declaration strings and not function parameter lists
            // (function parameter lists would be delimited by "," while declarations would
            // be delimited by ";").
               SgFunctionParameterList* parameterListDeclaration = dynamic_cast<SgFunctionParameterList*>(declaration);
               ROSE_ASSERT (parameterListDeclaration != NULL);
               SgInitializedNameList & argList = parameterListDeclaration->get_args();
               SgInitializedNameList::iterator i;
               for (i = argList.begin(); i != argList.end(); i++)
                  {
                    string typeNameString = (*i).get_type()->unparseToString();
                 // (9/8/2003) Bug Fix suggested by Nils
                 // string variableName   = (*i).get_name().str();
                    string variableName;
                    SgName nodeName   = (*i).get_name();
                    if(nodeName.str() != NULL)
                         variableName = nodeName.str();
                    else
                         variableName = "";

                    declarationString += typeNameString + " " + variableName + "; ";
                  }
               break;
             }

       // ignore this case ... not really a declaration
          case V_SgCtorInitializerList:
            // printf ("Ignore the SgCtorInitializerList (constructor initializer list) \n");
               break;

          case V_SgVariableDefinition:
               printf ("ERROR: SgVariableDefinition nodes not used in AST \n");
               ROSE_ABORT();
               break;

       // default case should always be an error
          default:
               printf ("Default reached in AST_Rewrite::AccumulatedDeclarationsAttribute::generateDeclarationString() \n");
               printf ("     declaration->sage_class_name() = %s \n",declaration->sage_class_name());
               ROSE_ABORT();
               break;
        }

  // Add a space to make it easier to read (not required)
     declarationString += " ";

  // printf ("For this scope: declarationString = %s \n",declarationString.c_str());

     return declarationString;
   }
Beispiel #14
0
string globalUnparseToString ( SgNode* astNode, SgUnparse_Info* inputUnparseInfoPointer )
{
  // This global function permits any SgNode (including it's subtree) to be turned into a string

  // DQ (3/2/2006): Let's make sure we have a valid IR node!
     ROSE_ASSERT(astNode != NULL);

     string returnString;

  // all options are now defined to be false. When these options can be passed in
  // from the prompt, these options will be set accordingly.
     bool _auto                         = false;
     bool linefile                      = false;
     bool useOverloadedOperators        = false;
     bool num                           = false;

  // It is an error to have this always turned off (e.g. pointer = this; will not unparse correctly)
     bool _this                         = true;

     bool caststring                    = false;
     bool _debug                        = false;
     bool _class                        = false;
     bool _forced_transformation_format = false;
     bool _unparse_includes             = false;

  // printf ("In globalUnparseToString(): astNode->sage_class_name() = %s \n",astNode->sage_class_name());

     Unparser_Opt roseOptions( _auto,
                               linefile,
                               useOverloadedOperators,
                               num,
                               _this,
                               caststring,
                               _debug,
                               _class,
                               _forced_transformation_format,
                               _unparse_includes );

     int lineNumber = 0;  // Zero indicates that ALL lines should be unparsed

     // Initialize the Unparser using a special string stream inplace of the usual file stream 
     ostringstream outputString;

     SgLocatedNode* locatedNode = isSgLocatedNode(astNode);
     string fileNameOfStatementsToUnparse;
     if (locatedNode == NULL)
        {
       // printf ("WARNING: applying AST -> string for non expression/statement AST objects \n");
          fileNameOfStatementsToUnparse = "defaultFileNameInGlobalUnparseToString";
        }
       else
        {
          ROSE_ASSERT (locatedNode != NULL);

       // DQ (5/31/2005): Get the filename from a traversal back through the parents to the SgFile
       // fileNameOfStatementsToUnparse = locatedNode->getFileName();
       // fileNameOfStatementsToUnparse = rose::getFileNameByTraversalBackToFileNode(locatedNode);
          if (locatedNode->get_parent() == NULL)
             {
            // DQ (7/29/2005):
            // Allow this function to be called with disconnected AST fragments not connected to 
            // a previously generated AST.  This happens in Qing's interface where AST fragements 
            // are built and meant to be unparsed.  Only the parent of the root of the AST 
            // fragement is expected to be NULL.
               fileNameOfStatementsToUnparse = locatedNode->getFileName();
             }
            else
             {
               fileNameOfStatementsToUnparse = rose::getFileNameByTraversalBackToFileNode(locatedNode);
             }
          
        }
     ROSE_ASSERT (fileNameOfStatementsToUnparse.size() > 0);

     Unparser roseUnparser ( &outputString, fileNameOfStatementsToUnparse, roseOptions, lineNumber );

  // Information that is passed down through the tree (inherited attribute)
  // Use the input SgUnparse_Info object if it is available.
     SgUnparse_Info* inheritedAttributeInfoPointer = NULL;
     if (inputUnparseInfoPointer != NULL)
        {
       // printf ("Using the input inputUnparseInfoPointer object \n");

       // Use the user provided SgUnparse_Info object
          inheritedAttributeInfoPointer = inputUnparseInfoPointer;
        }
       else
        {
       // DEFINE DEFAULT BEHAVIOUR FOR THE CASE WHEN NO inputUnparseInfoPointer (== NULL) IS 
       // PASSED AS ARGUMENT TO THE FUNCTION
       // printf ("Building a new Unparse_Info object \n");

       // If no input parameter has been specified then allocate one
       // inheritedAttributeInfoPointer = new SgUnparse_Info (NO_UNPARSE_INFO);
          inheritedAttributeInfoPointer = new SgUnparse_Info();
          ROSE_ASSERT (inheritedAttributeInfoPointer != NULL);

       // MS: 09/30/2003: comments de-activated in unparsing
          ROSE_ASSERT (inheritedAttributeInfoPointer->SkipComments() == false);

       // Skip all comments in unparsing
          inheritedAttributeInfoPointer->set_SkipComments();
          ROSE_ASSERT (inheritedAttributeInfoPointer->SkipComments() == true);
       // Skip all whitespace in unparsing (removed in generated string)
          inheritedAttributeInfoPointer->set_SkipWhitespaces();
          ROSE_ASSERT (inheritedAttributeInfoPointer->SkipWhitespaces() == true);

       // Skip all directives (macros are already substituted by the front-end, so this has no effect on those)
          inheritedAttributeInfoPointer->set_SkipCPPDirectives();
          ROSE_ASSERT (inheritedAttributeInfoPointer->SkipCPPDirectives() == true);
        }

     ROSE_ASSERT (inheritedAttributeInfoPointer != NULL);
     SgUnparse_Info & inheritedAttributeInfo = *inheritedAttributeInfoPointer;

  // Turn ON the error checking which triggers an error if the default SgUnparse_Info constructor is called
  // SgUnparse_Info::forceDefaultConstructorToTriggerError = true;

#if 1
  // DQ (10/19/2004): Cleaned up this code, remove this dead code after we are sure that this worked properly
  // Actually, this code is required to be this way, since after this branch the current function returns and
  // some data must be cleaned up differently!  So put this back and leave it this way, and remove the
  // "Implementation Note".

  // Both SgProject and SgFile are handled via recursive calls
     if ( (isSgProject(astNode) != NULL) || (isSgFile(astNode) != NULL) )
        {
       // printf ("Implementation Note: Put these cases (unparsing the SgProject and SgFile into the cases for nodes derived from SgSupport below! \n");

       // Handle recursive call for SgProject
          if (isSgProject(astNode) != NULL)
             {
               SgProject* project = isSgProject(astNode);
               ROSE_ASSERT(project != NULL);
               for (int i = 0; i < project->numberOfFiles(); i++)
                  {
                    SgFile* file = &(project->get_file(i));
                    ROSE_ASSERT(file != NULL);
                    string unparsedFileString = globalUnparseToString(file,inputUnparseInfoPointer);
                    string prefixString       = string("/* TOP:")      + string(rose::getFileName(file)) + string(" */ \n");
                    string suffixString       = string("\n/* BOTTOM:") + string(rose::getFileName(file)) + string(" */ \n\n");
                    returnString += prefixString + unparsedFileString + suffixString;
                  }
             }

       // Handle recursive call for SgFile
          if (isSgFile(astNode) != NULL)
             {
               SgFile* file = isSgFile(astNode);
               ROSE_ASSERT(file != NULL);
               SgGlobal* globalScope = file->get_root();
               ROSE_ASSERT(globalScope != NULL);
               returnString = globalUnparseToString(globalScope,inputUnparseInfoPointer);
             }
        }
       else
#endif
        {
       // DQ (1/12/2003): Only now try to trap use of SgUnparse_Info default constructor
       // Turn ON the error checking which triggers an error if the default SgUnparse_Info constructor is called
          SgUnparse_Info::set_forceDefaultConstructorToTriggerError(true);

          if (isSgStatement(astNode) != NULL)
             {
               SgStatement* stmt = isSgStatement(astNode);
               roseUnparser.unparseStatement ( stmt, inheritedAttributeInfo );
             }

          if (isSgExpression(astNode) != NULL)
             {
               SgExpression* expr = isSgExpression(astNode);
               roseUnparser.unparseExpression ( expr, inheritedAttributeInfo );
             }

          if (isSgType(astNode) != NULL)
             {
               SgType* type = isSgType(astNode);
               roseUnparser.unparseType ( type, inheritedAttributeInfo );
             }

          if (isSgSymbol(astNode) != NULL)
             {
               SgSymbol* symbol = isSgSymbol(astNode);
               roseUnparser.unparseSymbol ( symbol, inheritedAttributeInfo );
             }

          if (isSgSupport(astNode) != NULL)
             {
            // Handle different specific cases derived from SgSupport 
            // (e.g. template parameters and template arguments).
               switch (astNode->variantT())
                  {
#if 0
                    case V_SgProject:
                       {
                         SgProject* project = isSgProject(astNode);
                         ROSE_ASSERT(project != NULL);
                         for (int i = 0; i < project->numberOfFiles(); i++)
                            {
                              SgFile* file = &(project->get_file(i));
                              ROSE_ASSERT(file != NULL);
                              string unparsedFileString = globalUnparseToString(file,inputUnparseInfoPointer);
                              string prefixString       = string("/* TOP:")      + string(rose::getFileName(file)) + string(" */ \n");
                              string suffixString       = string("\n/* BOTTOM:") + string(rose::getFileName(file)) + string(" */ \n\n");
                              returnString += prefixString + unparsedFileString + suffixString;
                            }
                         break;
                       }
                    case V_SgFile:
                       {
                         SgFile* file = isSgFile(astNode);
                         ROSE_ASSERT(file != NULL);
                         SgGlobal* globalScope = file->get_root();
                         ROSE_ASSERT(globalScope != NULL);
                         returnString = globalUnparseToString(globalScope,inputUnparseInfoPointer);
                         break;
                       }
#endif
                    case V_SgTemplateParameter:
                       {
                         SgTemplateParameter* templateParameter = isSgTemplateParameter(astNode);
                         roseUnparser.unparseTemplateParameter(templateParameter,inheritedAttributeInfo);
                         break;
                       }
                    case V_SgTemplateArgument:
                       {
                         SgTemplateArgument* templateArgument = isSgTemplateArgument(astNode);
                         roseUnparser.unparseTemplateArgument(templateArgument,inheritedAttributeInfo);
                         break;
                       }
                    case V_SgInitializedName:
                       {
                      // QY: not sure how to implement this
                      // DQ (7/23/2004): This should unparse as a declaration 
                      // (type and name with initializer).
                         break;
                       }

                    case V_Sg_File_Info:
                       {
                      // DQ (5/11/2006): Not sure how or if we shoul implement this
                         break;
                       }

                 // Perhaps the support for SgFile and SgProject shoud be moved to this location?
                    default:
                         printf ("Error: default reached in node derived from SgSupport astNode = %s \n",astNode->sage_class_name());
                         ROSE_ABORT();
                }
             }

       // Turn OFF the error checking which triggers an if the default SgUnparse_Info constructor is called
          SgUnparse_Info::set_forceDefaultConstructorToTriggerError(false);

       // MS: following is the rewritten code of the above outcommented 
       //     code to support ostringstream instead of ostrstream.
          returnString = outputString.str();

       // Call function to tighten up the code to make it more dense
          if (inheritedAttributeInfo.SkipWhitespaces() == true)
             {
               returnString = roseUnparser.removeUnwantedWhiteSpace ( returnString );
             }

       // delete the allocated SgUnparse_Info object
          if (inputUnparseInfoPointer == NULL)
               delete inheritedAttributeInfoPointer;
        }

     return returnString;
   }
SgFunctionDeclaration * 
getFunctionDeclaration(SgFunctionCallExp *functionCall) 
{ 
  SgFunctionDeclaration *funcDec = NULL; 

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

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

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

      ROSE_ASSERT(funcDec != NULL);

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

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

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

      ROSE_ASSERT(funcDec != NULL);

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

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

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

      ROSE_ASSERT(funcDec != NULL);

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

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

      ROSE_ASSERT(funcDec != NULL);

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

  return funcDec; 
}