void
RemoveConstantFoldedValueViaParent::visit ( SgNode* node )
   {
  // This is an alternative implementation that allows us to handle expression that are not 
  // traversed in the AST (e.g. types like SgArrayType which can contain expressions).

     ROSE_ASSERT(node != NULL);

  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
#if 0
     printf ("In RemoveConstantFoldedValueViaParent::visit(): node = %p = %s \n",node,node->class_name().c_str());
#endif

  // DQ (10/12/2012): Turn this on so that we can detect failing IR nodes (failing later) that have valid originalExpressionTrees.
  // DQ (10/12/2012): Turn this back off because it appears to fail...
#if 0
     SgExpression* exp = isSgExpression(node);
     if (exp != NULL)
        {
          SgExpression* originalExpressionTree = exp->get_originalExpressionTree();
          if (originalExpressionTree != NULL)
             {
               SgNode* parent = exp->get_parent();
               if (parent != NULL)
                  {
                    printf ("Current IR node with SgExpression parent = %p = %s child = %p = %s originalExpressionTree = %p = %s \n",parent,parent->class_name().c_str(),node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str());
                    bool traceReplacement = true;
                    ConstantFoldedValueReplacer r(traceReplacement, exp);
                    parent->processDataMemberReferenceToPointers(&r);
                 // node->processDataMemberReferenceToPointers(&r);
                  }

            // Set the originalExpressionTree to NULL.
               exp->set_originalExpressionTree(NULL);

            // Set the parent of originalExpressionTree to be the parent of exp.
               originalExpressionTree->set_parent(parent);

            // And then delete the folded constant.
               SageInterface::deleteAST(exp);
             }
        }
#endif

     SgArrayType* arrayType = isSgArrayType(node);
     if (arrayType != NULL)
        {
#if 0
          printf ("Found an array type arrayType = %p arrayType->get_index() = %p \n",arrayType,arrayType->get_index());
#endif
          SgExpression* index = arrayType->get_index();
          if (index != NULL)
             {
#if 0
               printf ("Fixup array index = %p = %s (traverse index AST subtree) \n",index,index->class_name().c_str());
#endif
               RemoveConstantFoldedValue astFixupTraversal;
               astFixupTraversal.traverse(index);
#if 0
               printf ("DONE: Fixup array index = %p (traverse index AST) \n\n\n\n",index);
#endif
#if 0
               printf ("Found an array index = %p (fixup index directly) \n",index);
#endif
            // Handle the case where the original expression tree is at the root of the subtree.
               SgExpression* originalExpressionTree = index->get_originalExpressionTree();
               if (originalExpressionTree != NULL)
                  {
#if 0
                    printf ("Found an originalExpressionTree in the array index originalExpressionTree = %p \n",originalExpressionTree);
#endif
                 // DQ (6/12/2013): This appears to be a problem in EDG 4.7 (see test2011_117.C).
                    std::vector<SgExpression*> redundantChainOfOriginalExpressionTrees;
                    if (originalExpressionTree->get_originalExpressionTree() != NULL)
                       {
#if 0
                         printf ("Detected originalExpressionTree nested directly within the originalExpressionTree \n",
                              originalExpressionTree,originalExpressionTree->class_name().c_str(),
                              originalExpressionTree->get_originalExpressionTree(),originalExpressionTree->get_originalExpressionTree()->class_name().c_str());
#endif
                      // Loop to the end of the chain of original expressions (which EDG 4.7 should never have constructed).
                         while (originalExpressionTree->get_originalExpressionTree() != NULL)
                            {
#if 0
                              printf ("Looping through a chain of originalExpressionTrees \n");
#endif
                           // Save the list of redundnat nodes so that we can delete them properly.
                              redundantChainOfOriginalExpressionTrees.push_back(originalExpressionTree);

                              originalExpressionTree = originalExpressionTree->get_originalExpressionTree();
                            }
#if 0
                         printf ("Exiting as a test! \n");
                         ROSE_ASSERT(false);
#endif
                       }

                    arrayType->set_index(originalExpressionTree);
                    originalExpressionTree->set_parent(arrayType);

                    index->set_originalExpressionTree(NULL);

                 // printf ("DEBUGING: skip delete of index in array type \n");
                    delete index;

                 // DQ (6/12/2013): Delete the nodes that we had to skip over (caused by chain of redundant entries from EDG 4.7).
                    std::vector<SgExpression*>::iterator i = redundantChainOfOriginalExpressionTrees.begin();
                    while (i != redundantChainOfOriginalExpressionTrees.end())
                       {
#if 0
                         printf ("deleting the redundnat originalExpressionTree chain caused by EDG 4.7 (delete %p = %s) \n",*i,(*i)->class_name().c_str());
#endif
                         delete *i;
                         i++;
                       }

                    index = NULL;
                  }
             }
        }

     SgVariableDefinition* variableDefinition = isSgVariableDefinition(node);
     if (variableDefinition != NULL)
        {
#if 0
          printf ("Found a SgVariableDefinition \n");
#endif
          SgExpression* bitfieldExp = variableDefinition->get_bitfield();
          if (bitfieldExp != NULL)
             {
#if 0
               printf ("Fixup bitfieldExp = %p (traverse bitfieldExp AST subtree) \n",bitfieldExp);
#endif
               RemoveConstantFoldedValue astFixupTraversal;
               astFixupTraversal.traverse(bitfieldExp);

            // Handle the case where the original expression tree is at the root of the subtree.
               SgExpression* originalExpressionTree = bitfieldExp->get_originalExpressionTree();
               if (originalExpressionTree != NULL)
                  {
#if 0
                 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression.
                    variableDefinition->set_bitfield(originalExpressionTree);
                    originalExpressionTree->set_parent(variableDefinition);

                    bitfieldExp->set_originalExpressionTree(NULL);
                    delete bitfieldExp;
                    bitfieldExp = NULL;
#else
                 // The ROSE AST needs to be fixed to handle more general expressions for bitfield widths (this does not effect the CFG).
                 // TODO: Change the data type of the bitfield data member in SgVariableDefinition.

                 // DQ (1/20/2014): This has been done now.
                 // printf ("Member data bitfield widths need to be changed (in the ROSE IR) to support more general expressions (can't fix this original expression tree) \n");
#endif
#if 0
                 // This case is not handled yet!
                    printf ("Found an original expression tree in a bitfield expression \n");
                    ROSE_ASSERT(false);
#endif
                  }
             }
        }
   }
void
ConstantFoldedValueReplacer::operator()(SgNode*& key, const SgName & debugStringName, bool /* traverse */ traceReplacement)
   {
  // This function is used to replace the expression in an AST node and avoids explicitly handling all of the cases 
  // of where an IR node can exist in the AST (in this case expressions containing an opriginal expression tree could 
  // be in a lot of locations).

  // Note that the key will be a reference to the pointer for each data member of the IR node where: 
  //      node->processDataMemberReferenceToPointers(&r);
  // is called.

#if 0
     printf ("Inside of ConstantFoldedValueReplacer::operator() key = %p = %s = %s node = %p = %s = %s \n",
          key,(key != NULL) ? key->class_name().c_str() : "NULL",(key != NULL) ? SageInterface::get_name(key).c_str() : "NULL",
          targetNode,(targetNode != NULL) ? targetNode->class_name().c_str() : "NULL",(targetNode != NULL) ? SageInterface::get_name(targetNode).c_str() : "NULL");
#endif

     if (key != NULL)
        {
       // Now reset the pointer to the subtree identified as redundent with a
       // subtree in the original AST to the subtree in the original (merged) AST.

       // Note: targetNode is the IR node to be replaced (set in the ConstantFoldedValueReplacer constructor call).
          if (key == targetNode)
             {
#if 0
               printf ("Note that key == originalNode \n");
#endif
               SgExpression* keyExpression = isSgExpression(key);

            // DQ (9/17/2011): We don't want to eliminate references to enum values (see test2005_194.C).
            // Though I wonder if it could be that we are not distinguishing the enum value and the 
            // values of the enum variables (the order of the fields in the enum declaration).
               if (isSgEnumVal(keyExpression) == NULL)
                  {
                    if (keyExpression != NULL)
                       {
#if 0
                         printf ("Note that key is a valid expression keyExpression->get_originalExpressionTree() = %p \n",keyExpression->get_originalExpressionTree());
#endif
                         if (keyExpression->get_originalExpressionTree() != NULL)
                            {
#if 0
                              printf ("key contains a originalExpressionTree = %p = %s \n",keyExpression->get_originalExpressionTree(),keyExpression->get_originalExpressionTree()->class_name().c_str());
#endif

                           // DQ (10/8/2011): Added support for chains of expression trees.
                           // while (keyExpression->get_originalExpressionTree()->get_originalExpressionTree() != NULL)
                              while (keyExpression->get_originalExpressionTree()->get_originalExpressionTree() != NULL && isSgEnumVal(keyExpression->get_originalExpressionTree()) == NULL)
                                 {
                                   SgExpression* nestedOriginalExpressionTree = keyExpression->get_originalExpressionTree();
                                   ROSE_ASSERT(nestedOriginalExpressionTree != NULL);
#if 0
                                   printf ("Found a chain of original expression trees (iterate to find the end of the chain: keyExpression = %p = %s keyExpression->get_originalExpressionTree() = %p = %s \n",
                                        keyExpression,keyExpression->class_name().c_str(),nestedOriginalExpressionTree,nestedOriginalExpressionTree->class_name().c_str());
#endif
                                   keyExpression = nestedOriginalExpressionTree;
                                 }

                           // If this is an enum value, then we don't want the original expression tree (which 
                           // will otherwise be substituted into such places as SgCaseOptionStmt nodes, etc.).
                              SgEnumVal* enumValue = isSgEnumVal(keyExpression->get_originalExpressionTree());
                              if (enumValue != NULL)
                                 {
#if 0
                                   printf ("Detected case of enumValue = %p \n",enumValue);
#endif
                                   if (enumValue->get_originalExpressionTree())
                                      {
#if 0
                                        printf ("Deleting the original expression in the nested enumValue \n");
#endif
                                        deleteOriginalExpressionTree(enumValue->get_originalExpressionTree());
                                        enumValue->set_originalExpressionTree(NULL);
                                      }
                                 }

                              ROSE_ASSERT(keyExpression->get_originalExpressionTree() != NULL);
                              key = keyExpression->get_originalExpressionTree();
                              ROSE_ASSERT(key != NULL);

                           // Set the parent node
                              ROSE_ASSERT(keyExpression->get_originalExpressionTree() != NULL);
                              keyExpression->get_originalExpressionTree()->set_parent(targetNode->get_parent());

                              SgExpression* targetExpression = isSgExpression(targetNode);

                           // Clear the originalExpressionTree
                              targetExpression->set_originalExpressionTree(NULL);
                              ROSE_ASSERT(targetExpression->get_originalExpressionTree() == NULL);

                              targetExpression->set_parent(NULL);

                           // DQ (9/24/2011): This can be an expression tree (more than just a single IR node (see test2011_140.C).
                           // delete targetNode;
                              SageInterface::deleteAST(targetExpression);

                           // Reset the pointer to avoid any dangling pointer problems.
                              targetNode = NULL;
                            }
                       }
                      else
                       {
#if 0
                         printf ("key is not a SgExpression \n");
#endif
                       }
                  }
                 else
                  {
                 // For the case of a SgEnumVal, don't use the original expression tree (see test2005_194.C)
                 // The original expression tree holds the value used for the enum field, instead of the 
                 // reference to the correct enum field).
#if 0
                    printf ("ENUM VALUE special handling: we call deleteOriginalExpressionTree(keyExpression = %p) \n",keyExpression);
#endif
                    deleteOriginalExpressionTree(keyExpression);
                  }
             }
            else
             {
#if 0
               printf ("key != originalNode \n");
#endif
             }
        }
       else
        {
#if 0
          printf ("key == NULL \n");
#endif
        }

#if 0
     printf ("Leaving ConstantFoldedValueReplacer::operator() new reset key = %p = %s \n",key,(key != NULL) ? key->class_name().c_str() : "NULL");
#endif
   }