// Check if this is an A++ Array Reference
bool isAPPArray(SgNode *astNode) {

	SgVarRefExp* varRefExp = isSgVarRefExp(astNode);

	if (varRefExp == NULL)
		return false;

	SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
	ROSE_ASSERT(variableSymbol != NULL);
	SgInitializedName* initializedName = variableSymbol->get_declaration();
	ROSE_ASSERT(initializedName != NULL);
	SgName variableName = initializedName->get_name();

	// Now compute the offset to the index objects (form a special query for this???)

	SgType* type = variableSymbol->get_type();
	ROSE_ASSERT(type != NULL);

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

	// Recognize only these types at present
	if (typeName == "intArray" || typeName == "floatArray" || typeName == "doubleArray") {
		return true;
	}

	return false;
}
// first visits the VarRef and then creates entry in operandDatabase which is
// useful in expressionStatement transformation. Thus, we replace the VarRef
// at the end of the traversal and insert loops during traversal
ArrayAssignmentStatementQuerySynthesizedAttributeType ArrayAssignmentStatementTransformation::evaluateSynthesizedAttribute(
		SgNode* astNode,
		ArrayAssignmentStatementQueryInheritedAttributeType arrayAssignmentStatementQueryInheritedData,
		SubTreeSynthesizedAttributes synthesizedAttributeList) {
	// This function assembles the elements of the input list (a list of char*) to form the output (a single char*)

#if DEBUG
	printf ("\n$$$$$ TOP of evaluateSynthesizedAttribute (astNode = %s) (synthesizedAttributeList.size() = %d) \n",
			astNode->sage_class_name(),synthesizedAttributeList.size());
	//cout << " Ast node string: " << astNode->unparseToString() << endl;
#endif

	// Build the return value for this function
	ArrayAssignmentStatementQuerySynthesizedAttributeType returnSynthesizedAttribute(astNode);

	// Iterator used within several error checking loops (not sure we should declare it here!)
	vector<ArrayAssignmentStatementQuerySynthesizedAttributeType>::iterator i;

	// Make a reference to the global operand database
	OperandDataBaseType & operandDataBase = accumulatorValue.operandDataBase;

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

	// Build up a return string
	string returnString = "";

	string operatorString;

	// Need to handle all unary and binary operators and variables (but not much else)
	switch (astNode->variant()) {

	case FUNC_CALL: {

		// Error checking: Verify that we have a SgFunctionCallExp object
		SgFunctionCallExp* functionCallExpression = isSgFunctionCallExp(astNode);
		ROSE_ASSERT(functionCallExpression != NULL);

		string operatorName = TransformationSupport::getFunctionName(functionCallExpression);
		ROSE_ASSERT(operatorName.c_str() != NULL);

		string functionTypeName = TransformationSupport::getFunctionTypeName(functionCallExpression);

		if ((functionTypeName != "doubleArray") && (functionTypeName != "floatArray") && (functionTypeName
				!= "intArray")) {
			// Use this query to handle only A++ function call expressions
			// printf ("Break out of overloaded operator processing since type = %s is not to be processed \n",functionTypeName.c_str());
			break;
		} else {
			// printf ("Processing overloaded operator of type = %s \n",functionTypeName.c_str());
		}

		ROSE_ASSERT((functionTypeName == "doubleArray") || (functionTypeName == "floatArray") || (functionTypeName
				== "intArray"));

		// printf ("CASE FUNC_CALL: Overloaded operator = %s \n",operatorName.c_str());

		// Get the number of parameters to this function
		SgExprListExp* exprListExp = functionCallExpression->get_args();
		ROSE_ASSERT(exprListExp != NULL);

		SgExpressionPtrList & expressionPtrList = exprListExp->get_expressions();
		int numberOfParameters = expressionPtrList.size();

		TransformationSupport::operatorCodeType operatorCodeVariant =
				TransformationSupport::classifyOverloadedOperator(operatorName.c_str(), numberOfParameters);
		// printf ("CASE FUNC_CALL: numberOfParameters = %d operatorCodeVariant = %d \n",
		//      numberOfParameters,operatorCodeVariant);

		ROSE_ASSERT(operatorName.length() > 0);

		// Separating this case into additional cases makes up to some
		// extent for using a more specific higher level grammar.
		switch (operatorCodeVariant) {

		case TransformationSupport::ASSIGN_OPERATOR_CODE: {
			vector<ArrayOperandDataBase>::iterator lhs = operandDataBase.arrayOperandList.begin();
			vector<ArrayOperandDataBase>::iterator rhs = lhs;
			rhs++;
			while (rhs != operandDataBase.arrayOperandList.end()) {
				// look at the operands on the rhs for a match with the one on the lhs
				if ((*lhs).arrayVariableName == (*rhs).arrayVariableName) {
					// A loop dependence has been identified

					// Mark the synthesized attribute to record
					// the loop dependence within this statement
					returnSynthesizedAttribute.setLoopDependence(TRUE);
				}

				rhs++;
			}
			break;
		}

		default:
			break;
		}

		break;
	}
	case EXPR_STMT: {
		printf("Found a EXPR STMT expression %s\n", astNode->unparseToString().c_str());

		// The assembly associated with the SgExprStatement is what 
		// triggers the generation of the transformation string
		SgExprStatement* expressionStatement = isSgExprStatement(astNode);
		ROSE_ASSERT(expressionStatement != NULL);

		ArrayAssignmentStatementQuerySynthesizedAttributeType innerLoopTransformation =
				synthesizedAttributeList[SgExprStatement_expression];

		// Call another global support
		// Create appropriate macros, nested loops, etc
		expressionStatementTransformation(expressionStatement, arrayAssignmentStatementQueryInheritedData,
				innerLoopTransformation, operandDataBase);

		break;
	}

		//		case TransformationSupport::PARENTHESIS_OPERATOR_CODE: {
		//			ROSE_ASSERT (operatorName == "operator()");
		//			// printf ("Indexing of InternalIndex objects in not implemented yet! \n");
		//
		//			// Now get the operands out and search for the offsets in the index objects
		//
		//			// We only want to pass on the transformationOptions as inherited attributes
		//			// to the indexOffsetQuery
		//			// list<int> & transformationOptionList = arrayAssignmentStatementQueryInheritedData.getTransformationOptions();
		//
		//			// string offsetString;
		//			string indexOffsetString[6]; // = {NULL,NULL,NULL,NULL,NULL,NULL};
		//
		//			// retrieve the variable name from the data base (so that we can add the associated index object names)
		//			// printf ("WARNING (WHICH OPERAND TO SELECT): operandDataBase.size() = %d \n",operandDataBase.size());
		//			// ROSE_ASSERT (operandDataBase.size() == 1);
		//			// string arrayVariableName = returnSynthesizedAttribute.arrayOperandList[0].arrayVariableName;
		//			int lastOperandInDataBase = operandDataBase.size() - 1;
		//			ArrayOperandDataBase & arrayOperandDB = operandDataBase.arrayOperandList[lastOperandInDataBase];
		//			// string arrayVariableName =
		//			//      operandDataBase.arrayOperandList[operandDataBase.size()-1].arrayVariableName;
		//			string arrayVariableName = arrayOperandDB.arrayVariableName;
		//
		//			string arrayDataPointerNameSubstring = string("_") + arrayVariableName;
		//
		//			// printf ("***** WARNING: Need to get identifier from the database using the ArrayOperandDataBase::generateIdentifierString() function \n");
		//
		//			if (expressionPtrList.size() == 0) {
		//				// Case of A() (index object with no offset integer expression) Nothing to do here (I think???)
		//				printf("Special case of Indexing with no offset! exiting ... \n");
		//				ROSE_ABORT();
		//
		//				returnString = "";
		//			} else {
		//				// Get the value of the offsets (start the search from the functionCallExp)
		//				SgExprListExp* exprListExp = functionCallExpression->get_args();
		//				ROSE_ASSERT (exprListExp != NULL);
		//
		//				SgExpressionPtrList & expressionPtrList = exprListExp->get_expressions();
		//				SgExpressionPtrList::iterator i = expressionPtrList.begin();
		//
		//				// Case of indexing objects used within operator()
		//				int counter = 0;
		//				while (i != expressionPtrList.end()) {
		//					// printf ("Looking for the offset on #%d of %d (total) \n",counter,expressionPtrList.size());
		//
		//					// Build up the name of the final index variable (or at least give
		//					// it a unique number by dimension)
		//					string counterString = StringUtility::numberToString(counter + 1);
		//
		//					// Call another transformation mechanism to generate string for the index
		//					// expression (since we don't have an unparser mechanism in ROSE yet)
		//					indexOffsetString[counter] = IndexOffsetQuery::transformation(*i);
		//
		//					ROSE_ASSERT (indexOffsetString[counter].c_str() != NULL);
		//					// printf ("indexOffsetString [%d] = %s \n",counter,indexOffsetString[counter].c_str());
		//
		//					// Accumulate a list of all the InternalIndex, Index, and Range objects
		//					printf(" Warning - Need to handle indexNameList from the older code \n");
		//
		//					i++;
		//					counter++;
		//				}

		// Added VAR_REF case (moved from the local function)
	case VAR_REF: {
		// A VAR_REF has to output a string (the variable name)
#if DEBUG
		printf ("Found a variable reference expression \n");
#endif

		// Since we are at a leaf in the traversal of the AST this attribute list should a size of 0.
		ROSE_ASSERT(synthesizedAttributeList.size() == 0);

		SgVarRefExp* varRefExp = isSgVarRefExp(astNode);
		ROSE_ASSERT(varRefExp != NULL);
		SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
		ROSE_ASSERT(variableSymbol != NULL);
		SgInitializedName* initializedName = variableSymbol->get_declaration();
		ROSE_ASSERT(initializedName != NULL);
		SgName variableName = initializedName->get_name();

		string buffer;
		string indexOffsetString;

		// Now compute the offset to the index objects (form a special query for this???)

		SgType* type = variableSymbol->get_type();
		ROSE_ASSERT(type != NULL);

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

		// Recognize only these types at present
		if (typeName == "intArray" || typeName == "floatArray" || typeName == "doubleArray") {
			// Only define the variable name if we are using an object of array type
			// Copy the string from the SgName object to a string object
			string variableNameString = variableName.str();

#if DEBUG
			printf("Handle case of A++ array object VariableName: %s \n", variableNameString.c_str());
#endif

			if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) {
				cout << " Dim: " << arrayAssignmentStatementQueryInheritedData.arrayStatementDimension << endl;
				// The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData
				dimensionList.push_back(arrayAssignmentStatementQueryInheritedData.arrayStatementDimension);
			} else {
				dimensionList.push_back(6); // Default dimension for A++/P++
			}

			nodeList.push_back(isSgExpression(varRefExp));
			//processArrayRefExp(varRefExp, arrayAssignmentStatementQueryInheritedData);

			// Setup an intry in the synthesized attribute data base for this variable any
			// future results from analysis could be place there at this point as well
			// record the name in the synthesized attribute
			ROSE_ASSERT(operandDataBase.transformationOption > ArrayTransformationSupport::UnknownIndexingAccess);
			ArrayOperandDataBase arrayOperandDB = operandDataBase.setVariableName(variableNameString);
		}

		break;
	}

	default: {
		break;
	}
	} // End of main switch statement


#if DEBUG
	printf ("$$$$$ BOTTOM of arrayAssignmentStatementAssembly::evaluateSynthesizedAttribute (astNode = %s) \n",astNode->sage_class_name());
	printf ("      BOTTOM: returnString = \n%s \n",returnString.c_str());
#endif

	return returnSynthesizedAttribute;
}
// Constructs _A_pointer[SC_A(_1,_2)]
SgPntrArrRefExp* buildAPPArrayRef(SgNode* astNode,
		ArrayAssignmentStatementQueryInheritedAttributeType & arrayAssignmentStatementQueryInheritedData,
		OperandDataBaseType & operandDataBase, SgScopeStatement* scope, SgExprListExp* parameterExpList) {
#if DEBUG
	printf("Contructing A++ array reference object \n");
#endif

	string returnString;

	SgVarRefExp* varRefExp = isSgVarRefExp(astNode);
	ROSE_ASSERT(varRefExp != NULL);
	SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
	ROSE_ASSERT(variableSymbol != NULL);
	SgInitializedName* initializedName = variableSymbol->get_declaration();
	ROSE_ASSERT(initializedName != NULL);
	SgName variableName = initializedName->get_name();

	vector<SgExpression*> parameters;

	// Figure out the dimensionality of the statement globally
	int maxNumberOfIndexOffsets = 6; // default value for A++/P++ arrays
	ROSE_ASSERT(arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE);
	if (arrayAssignmentStatementQueryInheritedData.arrayStatementDimensionDefined == TRUE) {
		// The the globally computed array dimension from the arrayAssignmentStatementQueryInheritedData
		maxNumberOfIndexOffsets = arrayAssignmentStatementQueryInheritedData.arrayStatementDimension;
	}

	// Then we want the minimum of all the dimensions accesses (or is it the maximum?)
	for (int n = 0; n < maxNumberOfIndexOffsets; n++) {
		parameters.push_back(buildVarRefExp("_" + StringUtility::numberToString(n + 1), scope));
	}

	// Make a reference to the global operand database
	//OperandDataBaseType & operandDataBase = accumulatorValue.operandDataBase;

	SgType* type = variableSymbol->get_type();
	ROSE_ASSERT(type != NULL);

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

	// Copy the string from the SgName object to a string object
	string variableNameString = variableName.str();

	// Setup an intry in the synthesized attribute data base for this variable any
	// future results from analysis could be place there at this point as well
	// record the name in the synthesized attribute
	ROSE_ASSERT(operandDataBase.transformationOption > ArrayTransformationSupport::UnknownIndexingAccess);
	ArrayOperandDataBase arrayOperandDB = operandDataBase.setVariableName(variableNameString);

	// We could have specified in the inherited attribute that this array variable was
	// index and if so leave the value of $IDENTIFIER_STRING to be modified later in
	// the assembly of the operator() and if not do the string replacement on
	// $IDENTIFIER_STRING here (right now).

	returnString = string("$IDENTIFIER_STRING") + string("_pointer[SC") + string("$MACRO_NAME_SUBSTRING") + string("(")
			+ string("$OFFSET") + string(")]");

	string functionSuffix = "";
	SgPntrArrRefExp* pntrRefExp;

	cout << " arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() "
			<< arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() << endl;
	// The inherited attribute mechanism is not yet implimented
	if (arrayAssignmentStatementQueryInheritedData.getIsIndexedArrayOperand() == FALSE)
	//if(true)
	{
		// do the substitution of $OFFSET here since it our last chance
		// (offsetString is the list of index values "index1,index2,...,indexn")
		//returnString = StringUtility::copyEdit(returnString,"$OFFSET",offsetString);

		string operandIdentifier = arrayOperandDB.generateIdentifierString();
		// do the substitution of $IDENTIFIER_STRING here since it our last chance
		// if variable name is "A", generate: A_pointer[SC_A(index1,...)]
		// returnString = StringUtility::copyEdit (returnString,"$IDENTIFIER_STRING",variableNameString);
		ROSE_ASSERT(arrayOperandDB.indexingAccessCode > ArrayTransformationSupport::UnknownIndexingAccess);

		// Edit into place the name of the data pointer
		returnString = StringUtility::copyEdit(returnString, "$IDENTIFIER_STRING", operandIdentifier);

		// Optimize the case of uniform or unit indexing to generate a single subscript macro definition
		if ((arrayOperandDB.indexingAccessCode == ArrayTransformationSupport::UniformSizeUnitStride)
				|| (arrayOperandDB.indexingAccessCode == ArrayTransformationSupport::UniformSizeUniformStride))
			returnString = StringUtility::copyEdit(returnString, "$MACRO_NAME_SUBSTRING", "");
		else {
			returnString = StringUtility::copyEdit(returnString, "$MACRO_NAME_SUBSTRING", operandIdentifier);
			functionSuffix = operandIdentifier;
		}

		/* 
		 * Create SgPntrArrRefExp lhs is VarRefExp and rhs is SgFunctionCallExp
		 */
		SgVarRefExp* newVarRefExp = buildVarRefExp(operandIdentifier + "_pointer", scope);

		string functionName = "SC" + functionSuffix;

		SgFunctionCallExp* functionCallExp;
		if (parameterExpList == NULL)
			functionCallExp = buildFunctionCallExp(functionName, buildIntType(), buildExprListExp(parameters), scope);
		else
			functionCallExp = buildFunctionCallExp(functionName, buildIntType(), parameterExpList, scope);

		pntrRefExp = buildPntrArrRefExp(newVarRefExp, functionCallExp);

#if DEBUG
		cout << " pntrArrRefExp = " << pntrRefExp->unparseToString() << endl;
#endif 

	}

	return pntrRefExp;
}
示例#4
0
文件: f2cArray.C 项目: 8l/rose
void Fortran_to_C::linearizeArraySubscript(SgPntrArrRefExp* pntrArrRefExp)
{
  // get lhs operand
  SgVarRefExp*  arrayName = isSgVarRefExp(pntrArrRefExp->get_lhs_operand());
  // get array symbol
  SgVariableSymbol* arraySymbol = arrayName->get_symbol();
  // get array type and dim_info
  SgArrayType* arrayType = isSgArrayType(arraySymbol->get_type());
  ROSE_ASSERT(arrayType);
  SgExprListExp* dimInfo = arrayType->get_dim_info();

  // get rhs operand
  SgExprListExp*  arraySubscript = isSgExprListExp(pntrArrRefExp->get_rhs_operand());
  /*
    No matter it is single or multi dimensional array,  pntrArrRefExp always has a
    child, SgExprListExp, to store the subscript information.
  */
  if(arrayType->findBaseType()->variantT() == V_SgTypeString)
  {
    arraySubscript->prepend_expression(buildIntVal(1));
  }
  if(arraySubscript != NULL)
  {
    // get the list of subscript
    SgExpressionPtrList subscriptExprList = arraySubscript->get_expressions();
    // get the list of dimension inforamtion from array definition.
    SgExpressionPtrList dimExpressionPtrList = dimInfo->get_expressions();

    // Create new SgExpressionPtrList for the linearalized array subscript. 
    SgExpressionPtrList newSubscriptExprList;

    // rank info has to match between subscripts and dim_info
    ROSE_ASSERT(arraySubscript->get_expressions().size() == dimInfo->get_expressions().size());
   
    /*
      The subscript conversion is following this example:
      case 1:
      dimension a(d1,d2,d3,d4)    ====>   dimension a(d1*d2*d3*d4)
      a(s1,s2,s3,s4)              ====>   a(s1-1 + d1*(s2-1 + d2*( s3-1 + d3*(s4-1))))

      case 2:
      dimension a(d1L:d1H,d2L:d2H)    ====>   dimension a((d1H-d1L+1)*(d2H-d2L+1))
      a(s1,s2)              ====>   a(s1-d1L + (d1H-d1L+1)*(s2-d2L)) 
    */ 
    Rose_STL_Container<SgExpression*>::reverse_iterator j1 =  subscriptExprList.rbegin();
    Rose_STL_Container<SgExpression*>::reverse_iterator j2 =  dimExpressionPtrList.rbegin();
    // Need to know current size of both current and previous dimension
    SgExpression* newSubscript;
    while((j1 != subscriptExprList.rend()) && (j2 != dimExpressionPtrList.rend()))
    {
      //  get the lowerBound for each dimension
      SgExpression* newDimIndex;
      SgExpression* dimSize;
      /*  
        get the dimension size at each dimension
      */
      SgSubscriptExpression* subscriptExpression = isSgSubscriptExpression(*j2);
      /*
        This is for the 1st type of array declaration: a(10,15,20)
        Fortran is 1-based array.  Lowerbound is 1 by default.
      */
      if(subscriptExpression == NULL)
      {
        dimSize = deepCopy(*j2);
      }
      /*
        This is for the 2nd type of array declaration: a(1:10,5:15,10:20)
        Actual dimension size = upperBound - lowerBound + 1
      */
      else
      {
        dimSize = buildAddOp(buildSubtractOp(deepCopy(subscriptExpression->get_upperBound()),
                                             deepCopy(subscriptExpression->get_lowerBound())),
                                             buildIntVal(1));
      }

      // convert the 1-based subscript to 0-based subscript
      newDimIndex = get0basedIndex(*j1, *j2); 
      if(j1 != subscriptExprList.rbegin())
      {
        newSubscript = buildAddOp(newDimIndex,
                                  buildMultiplyOp(dimSize,newSubscript));
      }
      else
      {
        newSubscript = newDimIndex;
        delete(dimSize);
      }
      ++j1;
      ++j2;
    } // end of while loop

    newSubscriptExprList.push_back(newSubscript);
    SgExprListExp* newSubscriptList = buildExprListExp(newSubscriptExprList);
    // un-link and remove the rhs operand
    pntrArrRefExp->get_rhs_operand()->set_parent(NULL);
    removeList.push_back(pntrArrRefExp->get_rhs_operand());
    // add the new subscriptExpression into rhs operand
    pntrArrRefExp->set_rhs_operand(newSubscriptList);
    newSubscriptList->set_parent(pntrArrRefExp);
    
  } // end of arraySubscript != NULL
}
示例#5
0
文件: f2cArray.C 项目: 8l/rose
void Fortran_to_C::translateArraySubscript(SgPntrArrRefExp* pntrArrRefExp)
{
  // get lhs operand
  SgVarRefExp*  arrayName = isSgVarRefExp(pntrArrRefExp->get_lhs_operand());
  SgExpression* baseExp = isSgExpression(arrayName);
  // get array symbol
  SgVariableSymbol* arraySymbol = arrayName->get_symbol();
  // get array type and dim_info
  SgArrayType* arrayType = isSgArrayType(arraySymbol->get_type());
  ROSE_ASSERT(arrayType);
  SgExprListExp* dimInfo = arrayType->get_dim_info();

  // get rhs operand
  SgExprListExp*  arraySubscript = isSgExprListExp(pntrArrRefExp->get_rhs_operand());
  if(arrayType->findBaseType()->variantT() == V_SgTypeString)
  {
    arraySubscript->prepend_expression(buildIntVal(1));
  }
  /*
    No matter it is single or multi dimensional array,  pntrArrRefExp always has a
    child, SgExprListExp, to store the subscript information.
  */
  if(arraySubscript != NULL)
  {
    // get the list of subscript
    SgExpressionPtrList subscriptExprList = arraySubscript->get_expressions();
    // get the list of dimension inforamtion from array definition.
    SgExpressionPtrList dimExpressionPtrList = dimInfo->get_expressions();

    // Create new SgExpressionPtrList for the linearalized array subscript. 
    SgExpressionPtrList newSubscriptExprList;

    // rank info has to match between subscripts and dim_info
    ROSE_ASSERT(arraySubscript->get_expressions().size() == dimInfo->get_expressions().size());

    if(subscriptExprList.size() == 1)
    {
      Rose_STL_Container<SgExpression*>::iterator j1 =  subscriptExprList.begin();
      Rose_STL_Container<SgExpression*>::iterator j2 =  dimExpressionPtrList.begin();
      SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
      pntrArrRefExp->set_rhs_operand(newIndexExp);
    }
    else
    {
      Rose_STL_Container<SgExpression*>::reverse_iterator j1 =  subscriptExprList.rbegin();
      Rose_STL_Container<SgExpression*>::reverse_iterator j2 =  dimExpressionPtrList.rbegin();
      SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
      SgPntrArrRefExp* newPntrArrRefExp = buildPntrArrRefExp(baseExp, newIndexExp);
      baseExp->set_parent(newPntrArrRefExp);
      j1 = j1 + 1;
      j2 = j2 + 1;
      for(; j1< (subscriptExprList.rend()-1); ++j1, ++j2)
      {
        SgExpression* newIndexExp = get0basedIndex(*j1, *j2);
        baseExp = isSgExpression(newPntrArrRefExp);
        newPntrArrRefExp = buildPntrArrRefExp(baseExp, newIndexExp);
        baseExp->set_parent(newPntrArrRefExp);
      }
      newIndexExp = get0basedIndex(*j1, *j2);
      pntrArrRefExp->set_lhs_operand(newPntrArrRefExp);
      pntrArrRefExp->set_rhs_operand(newIndexExp);
      newIndexExp->set_parent(pntrArrRefExp);
    }
  }
}
InterleaveAcrossArraysCheckSynthesizedAttributeType
interleaveAcrossArraysCheck::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes )
{
    //cout << " Node: " << n->unparseToString() << endl;

    InterleaveAcrossArraysCheckSynthesizedAttributeType localResult;

    for (SynthesizedAttributesList::reverse_iterator child = childAttributes.rbegin(); child != childAttributes.rend(); child++)
    {
        InterleaveAcrossArraysCheckSynthesizedAttributeType childResult = *child;
        localResult.isArrayRef |= childResult.isArrayRef;
        localResult.isFunctionRefExp |= childResult.isFunctionRefExp;
    }


    if(isSgVariableDeclaration(n))
    {
        SgVariableDeclaration* varDecl = isSgVariableDeclaration(n);
        SgInitializedNamePtrList & varList = varDecl->get_variables();

        for(SgInitializedNamePtrList::iterator initIter = varList.begin(); initIter!=varList.end() ; initIter++)
        {
            SgInitializedName* var = *initIter;
            ROSE_ASSERT(var!=NULL);
            SgType *variableType = var->get_type();
            ROSE_ASSERT (variableType != NULL);
            string type = TransformationSupport::getTypeName(variableType);
            string variableName = var->get_name().str();

            //Case 6
            if(outputName == variableName)
            {
                cout << " ERROR: Substituting Array " << outputName << " already declared in the file." << endl;
                ROSE_ABORT();
            }

            if(type!="doubleArray" && type !="floatArray" && type!="intArray")
                return localResult;

#if DEBUG
            cout << " Var Name: " << variableName << " Type: " << type << endl;
#endif

            storeArrayReference(var, variableName, type );
        }
    }
    else if(isSgPntrArrRefExp(n))
    {
        SgVarRefExp* varRefExp = isSgVarRefExp(isSgPntrArrRefExp(n)->get_lhs_operand());

        if(varRefExp != NULL)
        {
            SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
            ROSE_ASSERT (variableSymbol != NULL);
            SgInitializedName* initializedName = variableSymbol->get_declaration();
            ROSE_ASSERT (initializedName != NULL);
            string variableName = initializedName->get_name().str();
            SgType* type = variableSymbol->get_type();
            ROSE_ASSERT (type != NULL);
            string typeName = TransformationSupport::getTypeName(type);

            // A++ Supported Arrays
            if(typeName !="doubleArray" && typeName !="floatArray" && typeName !="intArray")
                return localResult;

            // Check if variableName matches the input list
            if(transformation->containsInput(variableName))
                localResult.isArrayRef = true;
        }
    }
    else if(isSgFunctionCallExp(n))
    {
        // Case 1
        // Check for array being present in function Call
        if(localResult.isFunctionRefExp && localResult.isArrayRef)
        {
            cout << " ERROR: Array Reference present in a function call " << endl;
            ROSE_ABORT();
        }
    }
    else if(isSgFunctionRefExp(n))
    {
        localResult.isFunctionRefExp = true;
    }
    else if(isSgStatement(n))
    {
        //Case 2
        if(isContigousDecl)
        {
            cout << " ERROR: Array Declaration are not contigous. " << endl;
            ROSE_ABORT();
        }
    }
    return localResult;
}
示例#7
0
ExprSynAttr *examineExpr(SgExpression *expr, ostream &out) {
    stringstream ss1;
    stringstream ss2;
    stringstream ss3;
    SgExpression *e1;
    SgExpression *e2;
    SgBinaryOp *binop;
    SgUnaryOp *unaryop;
    SgType *type;
    ExprSynAttr *ret;
    ExprSynAttr *attr1, *attr2;
    string tmp_name;
    string tmp_type;

    string tmp2_name;
    string tmp2_type;

    if (expr == NULL)
        return NULL;

    ret = new ExprSynAttr();
    attr1 = NULL;
    attr2 = NULL;
    switch(expr->variantT()) {
        /* Begin UnaryOp */
        case V_SgMinusOp:
            out << "(-";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = attr1->type;
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= -" << attr1->result_var;
            ret->code << ";" << endl;
            break;
        case V_SgUnaryAddOp:
            out << "(+";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = attr1->type;
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= +" << attr1->result_var;
            ret->code << ";" << endl;
            break;
        case V_SgNotOp:
            out << "(!";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= (int)!" << attr1->result_var;
            ret->code << ";" << endl;

            break;
        case V_SgPointerDerefExp:
            out << "(*";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->basetype(attr1);
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= *" << attr1->result_var;
            ret->code << ";" << endl;

            break;
        case V_SgAddressOfOp:
             out << "(&";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";
            ret->type = attr1->type + "*";
            /* FIXME ret->sgtype */
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= &" << attr1->result_var;
            ret->code << ";" << endl;
             break;
        case V_SgMinusMinusOp:
            unaryop = isSgUnaryOp(expr);
            if (unaryop->get_mode()) {
                out << "(";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << "--)";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->new_tmp_name();
                ret->add_new_tmp_decl(ret->type, ret->result_var);
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();
                ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl;

                ret->code << attr1->result_var << "=" << attr1->result_var << "-1;" << endl;
            } else {
                out << "(--";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << ")";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->result_var = attr1->result_var;
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();

                ret->code << ret->result_var << "=" << attr1->result_var << "-1;" << endl;
            }
            break;
        case V_SgPlusPlusOp:
            unaryop = isSgUnaryOp(expr);
            if (unaryop->get_mode()) {
                out << "(";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << "++)";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->new_tmp_name();
                ret->add_new_tmp_decl(ret->type, ret->result_var);
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();
                ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl;

                ret->code << attr1->result_var << "=" << attr1->result_var << "+1;" << endl;

            } else {
                out << "(++";
                e1 = unaryop->get_operand();
                attr1 = examineExpr(e1, out);
                out << ")";

                ret->type = attr1->type;
                ret->sgtype = attr1->sgtype;

                ret->result_var = attr1->result_var;
                ret->union_tmp_decls(attr1);
                ret->code << attr1->code.str();

                ret->code << ret->result_var << "=" << attr1->result_var << "+1;" << endl;

            }
            break;
        case V_SgBitComplementOp:
            out << "(~";
            unaryop = isSgUnaryOp(expr);
            e1 = unaryop->get_operand();
            attr1 = examineExpr(e1, out);
            out << ")";

            ret->type = attr1->type;
            ret->sgtype = attr1->sgtype;
            ret->new_tmp_name();
            ret->add_new_tmp_decl(ret->type, ret->result_var);
            ret->union_tmp_decls(attr1);
            ret->code << attr1->code.str();
            ret->code << ret->result_var << "= ~" << attr1->result_var;
            ret->code << ";" << endl;

             break;
        case V_SgCastExp:
        {
            out << "(";
            SgCastExp *castexp = isSgCastExp(expr);
            e1 = castexp->get_operand();
            type = castexp->get_type();
            examineType(type, out);
            out << ")";
            attr1 = examineExpr(e1, out);

            stringstream casts;
            examineType(type, casts);
            ret->type = casts.str();
            ret->sgtype = type;
            ret->new_tmp_name(tmp_name);
            ret->union_tmp_decls(attr1, NULL);
            ret->add_new_tmp_decl(ret->type, tmp_name);

            ret->result_var = tmp_name;
            ret->code << attr1->code.str() << tmp_name;
            ret->code << "=(" << ret->type << ")" << attr1->result_var;
            ret->code << ";" << endl;
            break;
        }
        /* End UnaryOp */
        /* Begin BinaryOp */
        case V_SgEqualityOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "==";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;

            binop_noassign(ret, attr1, attr2, "==");
            break;
        case V_SgLessThanOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "<";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, "<");
            break;
        case V_SgGreaterThanOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ">";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, ">");
            break;
        case V_SgNotEqualOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "!=";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, "!=");
            break;
        case V_SgLessOrEqualOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "<=";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, "<=");
            break;
        case V_SgGreaterOrEqualOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ">=";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->type = "int";
            ret->sgtype = attr1->sgtype;
            binop_noassign(ret, attr1, attr2, ">=");
            break;
        case V_SgAddOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "+";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "+");
            break;
        case V_SgSubtractOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "-";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "-");
            break;
        case V_SgMultiplyOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "*";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "*");
            break;
        case V_SgDivideOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "/";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "/");
            break;
        case V_SgIntegerDivideOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "/";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "/");
            break;
        case V_SgModOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "%";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "%");
            break;
        case V_SgAndOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "&&";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            ret->type = "int";
            binop_noassign(ret, attr1, attr2, "&&");
            break;
        case V_SgOrOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "||";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            ret->type = "int";
            binop_noassign(ret, attr1, attr2, "||");
            break;
        case V_SgBitXorOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "^";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "^");
            break;
        case V_SgBitAndOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "&";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "&");
            break;
        case V_SgBitOrOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "|";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "|");
            break;
        case V_SgCommaOpExp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ",";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, ",");
            break;
        case V_SgLshiftOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "<<";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, "<<");
            break;
        case V_SgRshiftOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << ">>";
            attr2 = examineExpr(e2, out);
            out << ")";

            ret->cast_type(attr1, attr2);
            binop_noassign(ret, attr1, attr2, ">>");
            break;
        case V_SgAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);

            ret->union_tmp_decls(attr1, attr2);
            ret->result_var = attr1->result_var;
            ret->code << attr2->code.str() << attr1->code.str() << ret->result_var;
            ret->code << "=" << attr2->result_var;
            ret->code << ";" << endl;

            break;
        case V_SgPlusAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "+=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "+");
            break;
        case V_SgMinusAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "-=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "-");
            break;
        case V_SgAndAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "&=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "&");
            break;
        case V_SgIorAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "|=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "|");
            break;
        case V_SgMultAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "*=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "*");
            break;
        case V_SgDivAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "/=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "/");
            break;
        case V_SgModAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "%=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "%");
            break;
        case V_SgXorAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "^=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "^");
            break;
        case V_SgLshiftAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "<<=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, "<<");
            break;
        case V_SgRshiftAssignOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << ">>=";
            attr2 = examineExpr(e2, out);

            ret->cast_type(attr1, attr2);
            ret = binop_assign(ret, attr1, attr2, ">>");
            break;

        case V_SgExponentiationOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "ExpUnknown";
            attr2 = examineExpr(e2, out);
            out << ")";
            break;
        case V_SgConcatenationOp:
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            out << "(";
            attr1 = examineExpr(e1, out);
            out << "CatUnknown";
            attr2 = examineExpr(e2, out);
            out << ")";
            break;
        case V_SgPntrArrRefExp:
        {
            binop = isSgBinaryOp(expr);
            e1 = binop->get_lhs_operand();
            e2 = binop->get_rhs_operand();
            attr1 = examineExpr(e1, out);
            out << "[";
            attr2 = examineExpr(e2, out);
            out << "]";

            ret->basetype(attr1);
            ret->union_tmp_decls(attr1, attr2);

            ret->result_var = attr1->result_var + "[" + attr2->result_var + "]";

            ret->code << attr1->code.str() << attr2->code.str();
            break;
        }

        /* End BinaryOp */

        /* Begin variables */
        case V_SgVarRefExp:
        {
            stringstream casts;
            SgVarRefExp *varref = isSgVarRefExp(expr);
            if (NULL == varref)
                return NULL;
            SgVariableSymbol *svsym = varref->get_symbol();
            if (NULL == svsym)
                return NULL;
            out << svsym->get_name().getString();
            ret->result_var = svsym->get_name().getString();
            examineType(svsym->get_type(), casts);
            ret->type = casts.str();
            ret->sgtype = svsym->get_type();
            /*
            ret->new_tmp_name();
            examineType(svsym->get_type(), casts);
            ret->type = casts.str();
            ret->sgtype = svsym->get_type();
            ret->add_new_tmp_decl(ret->type, ret->result_var);

            ret->code << ret->result_var << " = " << svsym->get_name().getString();
            ret->code << ";" << endl;
            */
            break;
        }
        case V_SgLabelRefExp:
            SgLabelRefExp *labref = isSgLabelRefExp(expr);
            out << labref->get_name().getString();
            break;

        /* Begin Constants */
        case V_SgIntVal:
        {
            stringstream casts;

            SgIntVal *intval = isSgIntVal(expr);
            out << intval->get_value();
            casts << intval->get_value();

            ret->result_var = casts.str();
            ret->type = "int";
            ret->sgtype = intval->get_type();
            
            break;
        }
        case V_SgLongIntVal:
        {
            stringstream casts;

            SgLongIntVal *longval = isSgLongIntVal(expr);
            out << longval->get_value() << "L";
            casts << longval->get_value() << "L";

            ret->result_var = casts.str();
            ret->type = "long";
            ret->sgtype = longval->get_type();
            
            break;
        }
 
        case V_SgUnsignedIntVal:
        {
            stringstream casts;

            SgUnsignedIntVal *uintval = isSgUnsignedIntVal(expr);
            out << uintval->get_value() << "U";
            casts << uintval->get_value() << "U";
 
            ret->result_var = casts.str();
            ret->type = "unsigned";
            ret->sgtype = uintval->get_type();
            
            break;
        }
        case V_SgUnsignedLongVal:
        {
            stringstream casts;

            SgUnsignedLongVal *ulongval = isSgUnsignedLongVal(expr);
            out << ulongval->get_value() << "UL";
            casts << ulongval->get_value() << "UL";

            ret->result_var = casts.str();
            ret->type = "unsigned long";
            ret->sgtype = ulongval->get_type();
            
            break;
        }
        case V_SgDoubleVal:
        {
            stringstream casts;

            SgDoubleVal *doubleval = isSgDoubleVal(expr);
            out << doubleval->get_value();
            casts << doubleval->get_value();

            ret->result_var = casts.str();
            ret->type = "double";
            ret->sgtype = doubleval->get_type();
            
            break;
        }
        case V_SgFloatVal:
        {
            stringstream casts;

            SgFloatVal *floatval = isSgFloatVal(expr);
            out << floatval->get_value();
            casts << floatval->get_value();

            ret->result_var = casts.str();
            ret->type = "float";
            ret->sgtype = floatval->get_type();
            
            break;
        }
        default:
            out << "/* UNKNOWN EXPR[" << expr->class_name() << "](" << expr->variantT() << ") " << expr->unparseToString() << " */" << endl;
            cerr << "UNKNOWN EXPR[" << expr->class_name() << "] " << expr->unparseToString() << endl;
            break;
    }

    if (NULL != attr1)
        delete attr1;
    if (NULL != attr2)
        delete attr2;
    return ret;
}