Esempio n. 1
0
NodeQuerySynthesizedAttributeType
querySolverGrammarElementFromVariantVector ( 
   SgNode * astNode, 
   VariantVector targetVariantVector )
   {
  // This function extracts type nodes that would not be traversed so that they can
  // accumulated to a list.  The specific nodes collected into the list is controlled
  // by targetVariantVector.

     ROSE_ASSERT (astNode != NULL);
     NodeQuerySynthesizedAttributeType returnNodeList;

     Rose_STL_Container<SgNode*> nodesToVisitTraverseOnlyOnce;

     pushNewNode (&returnNodeList,targetVariantVector,astNode);

     vector<SgNode*>               succContainer      = astNode->get_traversalSuccessorContainer();
     vector<pair<SgNode*,string> > allNodesInSubtree  = astNode->returnDataMemberPointers();

     if( succContainer.size() != allNodesInSubtree.size() )
     for(vector<pair<SgNode*,string> >::iterator iItr = allNodesInSubtree.begin(); iItr!= allNodesInSubtree.end();
         ++iItr )
       if( isSgType(iItr->first) != NULL  )
         if(std::find(succContainer.begin(),succContainer.end(),iItr->first) == succContainer.end() )
           pushNewNode (&returnNodeList,targetVariantVector,iItr->first);

     
     return returnNodeList;
   } /* End function querySolverUnionFields() */
Esempio n. 2
0
//---------------------------------------------------------------------------------
//
//  Parse RBBI rules.   The state machine for rules parsing is here.
//                      The state tables are hand-written in the file rbbirpt.txt,
//                      and converted to the form used here by a perl
//                      script rbbicst.pl
//
//---------------------------------------------------------------------------------
void RBBIRuleScanner::parse() {
    uint16_t                state;
    const RBBIRuleTableEl  *tableEl;

    if (U_FAILURE(*fRB->fStatus)) {
        return;
    }

    state = 1;
    nextChar(fC);
    //
    // Main loop for the rule parsing state machine.
    //   Runs once per state transition.
    //   Each time through optionally performs, depending on the state table,
    //      - an advance to the the next input char
    //      - an action to be performed.
    //      - pushing or popping a state to/from the local state return stack.
    //
    for (;;) {
        //  Bail out if anything has gone wrong.
        //  RBBI rule file parsing stops on the first error encountered.
        if (U_FAILURE(*fRB->fStatus)) {
            break;
        }

        // Quit if state == 0.  This is the normal way to exit the state machine.
        //
        if (state == 0) {
            break;
        }

        // Find the state table element that matches the input char from the rule, or the
        //    class of the input character.  Start with the first table row for this
        //    state, then linearly scan forward until we find a row that matches the
        //    character.  The last row for each state always matches all characters, so
        //    the search will stop there, if not before.
        //
        tableEl = &gRuleParseStateTable[state];
#ifdef RBBI_DEBUG
        if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) {
            RBBIDebugPrintf("char, line, col = (\'%c\', %d, %d)    state=%s ",
                            fC.fChar, fLineNum, fCharNum, RBBIRuleStateNames[state]);
        }
#endif

        for (;;) {
#ifdef RBBI_DEBUG
            if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) {
                RBBIDebugPrintf(".");
            }
#endif
            if (tableEl->fCharClass < 127 && fC.fEscaped == FALSE &&   tableEl->fCharClass == fC.fChar) {
                // Table row specified an individual character, not a set, and
                //   the input character is not escaped, and
                //   the input character matched it.
                break;
            }
            if (tableEl->fCharClass == 255) {
                // Table row specified default, match anything character class.
                break;
            }
            if (tableEl->fCharClass == 254 && fC.fEscaped)  {
                // Table row specified "escaped" and the char was escaped.
                break;
            }
            if (tableEl->fCharClass == 253 && fC.fEscaped &&
                    (fC.fChar == 0x50 || fC.fChar == 0x70 ))  {
                // Table row specified "escaped P" and the char is either 'p' or 'P'.
                break;
            }
            if (tableEl->fCharClass == 252 && fC.fChar == (UChar32)-1)  {
                // Table row specified eof and we hit eof on the input.
                break;
            }

            if (tableEl->fCharClass >= 128 && tableEl->fCharClass < 240 &&   // Table specs a char class &&
                    fC.fEscaped == FALSE &&                                      //   char is not escaped &&
                    fC.fChar != (UChar32)-1) {                                   //   char is not EOF
                UnicodeSet *uniset = fRuleSets[tableEl->fCharClass-128];
                if (uniset->contains(fC.fChar)) {
                    // Table row specified a character class, or set of characters,
                    //   and the current char matches it.
                    break;
                }
            }

            // No match on this row, advance to the next  row for this state,
            tableEl++;
        }
        if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "scan")) {
            RBBIDebugPuts("");
        }

        //
        // We've found the row of the state table that matches the current input
        //   character from the rules string.
        // Perform any action specified  by this row in the state table.
        if (doParseActions((EParseAction)tableEl->fAction) == FALSE) {
            // Break out of the state machine loop if the
            //   the action signalled some kind of error, or
            //   the action was to exit, occurs on normal end-of-rules-input.
            break;
        }

        if (tableEl->fPushState != 0) {
            fStackPtr++;
            if (fStackPtr >= kStackSize) {
                error(U_BRK_INTERNAL_ERROR);
                RBBIDebugPuts("RBBIRuleScanner::parse() - state stack overflow.");
                fStackPtr--;
            }
            fStack[fStackPtr] = tableEl->fPushState;
        }

        if (tableEl->fNextChar) {
            nextChar(fC);
        }

        // Get the next state from the table entry, or from the
        //   state stack if the next state was specified as "pop".
        if (tableEl->fNextState != 255) {
            state = tableEl->fNextState;
        } else {
            state = fStack[fStackPtr];
            fStackPtr--;
            if (fStackPtr < 0) {
                error(U_BRK_INTERNAL_ERROR);
                RBBIDebugPuts("RBBIRuleScanner::parse() - state stack underflow.");
                fStackPtr++;
            }
        }

    }

    //
    // If there were NO user specified reverse rules, set up the equivalent of ".*;"
    //
    if (fRB->fReverseTree == NULL) {
        fRB->fReverseTree  = pushNewNode(RBBINode::opStar);
        RBBINode  *operand = pushNewNode(RBBINode::setRef);
        findSetFor(kAny, operand);
        fRB->fReverseTree->fLeftChild = operand;
        operand->fParent              = fRB->fReverseTree;
        fNodeStackPtr -= 2;
    }


    //
    // Parsing of the input RBBI rules is complete.
    // We now have a parse tree for the rule expressions
    // and a list of all UnicodeSets that are referenced.
    //
#ifdef RBBI_DEBUG
    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "symbols")) {
        fSymbolTable->rbbiSymtablePrint();
    }
    if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "ptree"))
    {
        RBBIDebugPrintf("Completed Forward Rules Parse Tree...\n");
        fRB->fForwardTree->printTree(TRUE);
        RBBIDebugPrintf("\nCompleted Reverse Rules Parse Tree...\n");
        fRB->fReverseTree->printTree(TRUE);
        RBBIDebugPrintf("\nCompleted Safe Point Forward Rules Parse Tree...\n");
        fRB->fSafeFwdTree->printTree(TRUE);
        RBBIDebugPrintf("\nCompleted Safe Point Reverse Rules Parse Tree...\n");
        fRB->fSafeRevTree->printTree(TRUE);
    }
#endif
}
Esempio n. 3
0
//----------------------------------------------------------------------------------------
//
//  doParseAction        Do some action during rule parsing.
//                       Called by the parse state machine.
//                       Actions build the parse tree and Unicode Sets,
//                       and maintain the parse stack for nested expressions.
//
//                       TODO:  unify EParseAction and RBBI_RuleParseAction enum types.
//                              They represent exactly the same thing.  They're separate
//                              only to work around enum forward declaration restrictions
//                              in some compilers, while at the same time avoiding multiple
//                              definitions problems.  I'm sure that there's a better way.
//
//----------------------------------------------------------------------------------------
UBool RBBIRuleScanner::doParseActions(EParseAction action)
{
    RBBINode *n       = NULL;

    UBool   returnVal = TRUE;

    switch ((RBBI_RuleParseAction)action) {

    case doExprStart:
        pushNewNode(RBBINode::opStart);
        fRuleNum++;
        break;


    case doExprOrOperator:
    {
        fixOpStack(RBBINode::precOpCat);
        RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
        RBBINode  *orNode      = pushNewNode(RBBINode::opOr);
        orNode->fLeftChild     = operandNode;
        operandNode->fParent   = orNode;
    }
    break;

    case doExprCatOperator:
        // concatenation operator.
        // For the implicit concatenation of adjacent terms in an expression that are
        //   not separated by any other operator.  Action is invoked between the
        //   actions for the two terms.
    {
        fixOpStack(RBBINode::precOpCat);
        RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
        RBBINode  *catNode     = pushNewNode(RBBINode::opCat);
        catNode->fLeftChild    = operandNode;
        operandNode->fParent   = catNode;
    }
    break;

    case doLParen:
        // Open Paren.
        //   The openParen node is a dummy operation type with a low precedence,
        //     which has the affect of ensuring that any real binary op that
        //     follows within the parens binds more tightly to the operands than
        //     stuff outside of the parens.
        pushNewNode(RBBINode::opLParen);
        break;

    case doExprRParen:
        fixOpStack(RBBINode::precLParen);
        break;

    case doNOP:
        break;

    case doStartAssign:
        // We've just scanned "$variable = "
        // The top of the node stack has the $variable ref node.

        // Save the start position of the RHS text in the StartExpression node
        //   that precedes the $variableReference node on the stack.
        //   This will eventually be used when saving the full $variable replacement
        //   text as a string.
        n = fNodeStack[fNodeStackPtr-1];
        n->fFirstPos = fNextIndex;              // move past the '='

        // Push a new start-of-expression node; needed to keep parse of the
        //   RHS expression happy.
        pushNewNode(RBBINode::opStart);
        break;




    case doEndAssign:
    {
        // We have reached the end of an assignement statement.
        //   Current scan char is the ';' that terminates the assignment.

        // Terminate expression, leaves expression parse tree rooted in TOS node.
        fixOpStack(RBBINode::precStart);

        RBBINode *startExprNode  = fNodeStack[fNodeStackPtr-2];
        RBBINode *varRefNode     = fNodeStack[fNodeStackPtr-1];
        RBBINode *RHSExprNode    = fNodeStack[fNodeStackPtr];

        // Save original text of right side of assignment, excluding the terminating ';'
        //  in the root of the node for the right-hand-side expression.
        RHSExprNode->fFirstPos = startExprNode->fFirstPos;
        RHSExprNode->fLastPos  = fScanIndex;
        fRB->fRules.extractBetween(RHSExprNode->fFirstPos, RHSExprNode->fLastPos, RHSExprNode->fText);

        // Expression parse tree becomes l. child of the $variable reference node.
        varRefNode->fLeftChild = RHSExprNode;
        RHSExprNode->fParent   = varRefNode;

        // Make a symbol table entry for the $variableRef node.
        fSymbolTable->addEntry(varRefNode->fText, varRefNode, *fRB->fStatus);
        if (U_FAILURE(*fRB->fStatus)) {
            // This is a round-about way to get the parse position set
            //  so that duplicate symbols error messages include a line number.
            UErrorCode t = *fRB->fStatus;
            *fRB->fStatus = U_ZERO_ERROR;
            error(t);
        }

        // Clean up the stack.
        delete startExprNode;
        fNodeStackPtr-=3;
        break;
    }

    case doEndOfRule:
    {
        fixOpStack(RBBINode::precStart);      // Terminate expression, leaves expression
        if (U_FAILURE(*fRB->fStatus)) {       //   parse tree rooted in TOS node.
            break;
        }
#ifdef RBBI_DEBUG
        if (fRB->fDebugEnv && uprv_strstr(fRB->fDebugEnv, "rtree")) {
            printNodeStack("end of rule");
        }
#endif
        U_ASSERT(fNodeStackPtr == 1);

        // If this rule includes a look-ahead '/', add a endMark node to the
        //   expression tree.
        if (fLookAheadRule) {
            RBBINode  *thisRule       = fNodeStack[fNodeStackPtr];
            RBBINode  *endNode        = pushNewNode(RBBINode::endMark);
            RBBINode  *catNode        = pushNewNode(RBBINode::opCat);
            fNodeStackPtr -= 2;
            catNode->fLeftChild       = thisRule;
            catNode->fRightChild      = endNode;
            fNodeStack[fNodeStackPtr] = catNode;
            endNode->fVal             = fRuleNum;
            endNode->fLookAheadEnd    = TRUE;
        }

        // All rule expressions are ORed together.
        // The ';' that terminates an expression really just functions as a '|' with
        //   a low operator prededence.
        //
        // Each of the four sets of rules are collected separately.
        //  (forward, reverse, safe_forward, safe_reverse)
        //  OR this rule into the appropriate group of them.
        //
        RBBINode **destRules = (fReverseRule? &fRB->fReverseTree : fRB->fDefaultTree);

        if (*destRules != NULL) {
            // This is not the first rule encounted.
            // OR previous stuff  (from *destRules)
            // with the current rule expression (on the Node Stack)
            //  with the resulting OR expression going to *destRules
            //
            RBBINode  *thisRule    = fNodeStack[fNodeStackPtr];
            RBBINode  *prevRules   = *destRules;
            RBBINode  *orNode      = pushNewNode(RBBINode::opOr);
            orNode->fLeftChild     = prevRules;
            prevRules->fParent     = orNode;
            orNode->fRightChild    = thisRule;
            thisRule->fParent      = orNode;
            *destRules             = orNode;
        }
        else
        {
            // This is the first rule encountered (for this direction).
            // Just move its parse tree from the stack to *destRules.
            *destRules = fNodeStack[fNodeStackPtr];
        }
        fReverseRule   = FALSE;   // in preparation for the next rule.
        fLookAheadRule = FALSE;
        fNodeStackPtr  = 0;
    }
    break;


    case doRuleError:
        error(U_BRK_RULE_SYNTAX);
        returnVal = FALSE;
        break;


    case doVariableNameExpectedErr:
        error(U_BRK_RULE_SYNTAX);
        break;


    //
    //  Unary operands  + ? *
    //    These all appear after the operand to which they apply.
    //    When we hit one, the operand (may be a whole sub expression)
    //    will be on the top of the stack.
    //    Unary Operator becomes TOS, with the old TOS as its one child.
    case doUnaryOpPlus:
    {
        RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
        RBBINode  *plusNode    = pushNewNode(RBBINode::opPlus);
        plusNode->fLeftChild   = operandNode;
        operandNode->fParent   = plusNode;
    }
    break;

    case doUnaryOpQuestion:
    {
        RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
        RBBINode  *qNode       = pushNewNode(RBBINode::opQuestion);
        qNode->fLeftChild      = operandNode;
        operandNode->fParent   = qNode;
    }
    break;

    case doUnaryOpStar:
    {
        RBBINode  *operandNode = fNodeStack[fNodeStackPtr--];
        RBBINode  *starNode    = pushNewNode(RBBINode::opStar);
        starNode->fLeftChild   = operandNode;
        operandNode->fParent   = starNode;
    }
    break;

    case doRuleChar:
        // A "Rule Character" is any single character that is a literal part
        // of the regular expression.  Like a, b and c in the expression "(abc*) | [:L:]"
        // These are pretty uncommon in break rules; the terms are more commonly
        //  sets.  To keep things uniform, treat these characters like as
        // sets that just happen to contain only one character.
    {
        n = pushNewNode(RBBINode::setRef);
        findSetFor(fC.fChar, n);
        n->fFirstPos = fScanIndex;
        n->fLastPos  = fNextIndex;
        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
        break;
    }

    case doDotAny:
        // scanned a ".", meaning match any single character.
    {
        n = pushNewNode(RBBINode::setRef);
        findSetFor(kAny, n);
        n->fFirstPos = fScanIndex;
        n->fLastPos  = fNextIndex;
        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
        break;
    }

    case doSlash:
        // Scanned a '/', which identifies a look-ahead break position in a rule.
        n = pushNewNode(RBBINode::lookAhead);
        n->fVal      = fRuleNum;
        n->fFirstPos = fScanIndex;
        n->fLastPos  = fNextIndex;
        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
        fLookAheadRule = TRUE;
        break;


    case doStartTagValue:
        // Scanned a '{', the opening delimiter for a tag value within a rule.
        n = pushNewNode(RBBINode::tag);
        n->fVal      = 0;
        n->fFirstPos = fScanIndex;
        n->fLastPos  = fNextIndex;
        break;

    case doTagDigit:
        // Just scanned a decimal digit that's part of a tag value
    {
        n = fNodeStack[fNodeStackPtr];
        uint32_t v = u_charDigitValue(fC.fChar);
        U_ASSERT(v < 10);
        n->fVal = n->fVal*10 + v;
        break;
    }

    case doTagValue:
        n = fNodeStack[fNodeStackPtr];
        n->fLastPos = fNextIndex;
        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
        break;

    case doTagExpectedError:
        error(U_BRK_MALFORMED_RULE_TAG);
        returnVal = FALSE;
        break;

    case doOptionStart:
        // Scanning a !!option.   At the start of string.
        fOptionStart = fScanIndex;
        break;

    case doOptionEnd:
    {
        UnicodeString opt(fRB->fRules, fOptionStart, fScanIndex-fOptionStart);
        if (opt == UNICODE_STRING("chain", 5)) {
            fRB->fChainRules = TRUE;
        } else if (opt == UNICODE_STRING("LBCMNoChain", 11)) {
            fRB->fLBCMNoChain = TRUE;
        } else if (opt == UNICODE_STRING("forward", 7)) {
            fRB->fDefaultTree   = &fRB->fForwardTree;
        } else if (opt == UNICODE_STRING("reverse", 7)) {
            fRB->fDefaultTree   = &fRB->fReverseTree;
        } else if (opt == UNICODE_STRING("safe_forward", 12)) {
            fRB->fDefaultTree   = &fRB->fSafeFwdTree;
        } else if (opt == UNICODE_STRING("safe_reverse", 12)) {
            fRB->fDefaultTree   = &fRB->fSafeRevTree;
        } else if (opt == UNICODE_STRING("lookAheadHardBreak", 18)) {
            fRB->fLookAheadHardBreak = TRUE;
        } else {
            error(U_BRK_UNRECOGNIZED_OPTION);
        }
    }
    break;

    case doReverseDir:
        fReverseRule = TRUE;
        break;

    case doStartVariableName:
        n = pushNewNode(RBBINode::varRef);
        if (U_FAILURE(*fRB->fStatus)) {
            break;
        }
        n->fFirstPos = fScanIndex;
        break;

    case doEndVariableName:
        n = fNodeStack[fNodeStackPtr];
        if (n==NULL || n->fType != RBBINode::varRef) {
            error(U_BRK_INTERNAL_ERROR);
            break;
        }
        n->fLastPos = fScanIndex;
        fRB->fRules.extractBetween(n->fFirstPos+1, n->fLastPos, n->fText);
        // Look the newly scanned name up in the symbol table
        //   If there's an entry, set the l. child of the var ref to the replacement expression.
        //   (We also pass through here when scanning assignments, but no harm is done, other
        //    than a slight wasted effort that seems hard to avoid.  Lookup will be null)
        n->fLeftChild = fSymbolTable->lookupNode(n->fText);
        break;

    case doCheckVarDef:
        n = fNodeStack[fNodeStackPtr];
        if (n->fLeftChild == NULL) {
            error(U_BRK_UNDEFINED_VARIABLE);
            returnVal = FALSE;
        }
        break;

    case doExprFinished:
        break;

    case doRuleErrorAssignExpr:
        error(U_BRK_ASSIGN_ERROR);
        returnVal = FALSE;
        break;

    case doExit:
        returnVal = FALSE;
        break;

    case doScanUnicodeSet:
        scanSet();
        break;

    default:
        error(U_BRK_INTERNAL_ERROR);
        returnVal = FALSE;
        break;
    }
    return returnVal;
}
Esempio n. 4
0
//---------------------------------------------------------------------------------
//
//  scanSet    Construct a UnicodeSet from the text at the current scan
//             position.  Advance the scan position to the first character
//             after the set.
//
//             A new RBBI setref node referring to the set is pushed onto the node
//             stack.
//
//             The scan position is normally under the control of the state machine
//             that controls rule parsing.  UnicodeSets, however, are parsed by
//             the UnicodeSet constructor, not by the RBBI rule parser.
//
//---------------------------------------------------------------------------------
void RBBIRuleScanner::scanSet() {
    UnicodeSet    *uset;
    ParsePosition  pos;
    int            startPos;
    int            i;

    if (U_FAILURE(*fRB->fStatus)) {
        return;
    }

    pos.setIndex(fScanIndex);
    startPos = fScanIndex;
    UErrorCode localStatus = U_ZERO_ERROR;
    uset = new UnicodeSet(fRB->fRules, pos, USET_IGNORE_SPACE,
                          fSymbolTable,
                          localStatus);
    if (U_FAILURE(localStatus)) {
        //  TODO:  Get more accurate position of the error from UnicodeSet's return info.
        //         UnicodeSet appears to not be reporting correctly at this time.
#ifdef RBBI_DEBUG
        RBBIDebugPrintf("UnicodeSet parse postion.ErrorIndex = %d\n", pos.getIndex());
#endif
        error(localStatus);
        delete uset;
        return;
    }

    // Verify that the set contains at least one code point.
    //
    if (uset->isEmpty()) {
        // This set is empty.
        //  Make it an error, because it almost certainly is not what the user wanted.
        //  Also, avoids having to think about corner cases in the tree manipulation code
        //   that occurs later on.
        error(U_BRK_RULE_EMPTY_SET);
        delete uset;
        return;
    }


    // Advance the RBBI parse postion over the UnicodeSet pattern.
    //   Don't just set fScanIndex because the line/char positions maintained
    //   for error reporting would be thrown off.
    i = pos.getIndex();
    for (;;) {
        if (fNextIndex >= i) {
            break;
        }
        nextCharLL();
    }

    if (U_SUCCESS(*fRB->fStatus)) {
        RBBINode         *n;

        n = pushNewNode(RBBINode::setRef);
        n->fFirstPos = startPos;
        n->fLastPos  = fNextIndex;
        fRB->fRules.extractBetween(n->fFirstPos, n->fLastPos, n->fText);
        //  findSetFor() serves several purposes here:
        //     - Adopts storage for the UnicodeSet, will be responsible for deleting.
        //     - Mantains collection of all sets in use, needed later for establishing
        //          character categories for run time engine.
        //     - Eliminates mulitiple instances of the same set.
        //     - Creates a new uset node if necessary (if this isn't a duplicate.)
        findSetFor(n->fText, n, uset);
    }

}
Esempio n. 5
0
// DQ (4/7/2004): Added to support more general lookup of data in the AST (vector of variants)
void* querySolverGrammarElementFromVariantVector ( SgNode * astNode, VariantVector targetVariantVector,  NodeQuerySynthesizedAttributeType* returnNodeList )
   {
  // This function extracts type nodes that would not be traversed so that they can
  // accumulated to a list.  The specific nodes collected into the list is controlled
  // by targetVariantVector.

     ROSE_ASSERT (astNode != NULL);

#if 0
     printf ("Inside of void* querySolverGrammarElementFromVariantVector() astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     Rose_STL_Container<SgNode*> nodesToVisitTraverseOnlyOnce;

     pushNewNode (returnNodeList,targetVariantVector,astNode);

     vector<SgNode*>               succContainer      = astNode->get_traversalSuccessorContainer();
     vector<pair<SgNode*,string> > allNodesInSubtree  = astNode->returnDataMemberPointers();

#if 0
     printf ("succContainer.size()     = %zu \n",succContainer.size());
     printf ("allNodesInSubtree.size() = %zu \n",allNodesInSubtree.size());
#endif

     if ( succContainer.size() != allNodesInSubtree.size() )
        {
          for (vector<pair<SgNode*,string> >::iterator iItr = allNodesInSubtree.begin(); iItr!= allNodesInSubtree.end(); ++iItr )
             {
#if 0
               if ( iItr->first != NULL  )
                  {
                 // printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str());
                    printf ("iItr->first = %p \n",iItr->first);
                    printf ("iItr->first = %p = %s \n",iItr->first,iItr->first->class_name().c_str());
                  }
#endif
            // DQ (7/27/2014): Check if this is always non-NULL.
            // ROSE_ASSERT(iItr->first != NULL);
#if 0
               if (iItr->first != NULL)
                  {
                 // printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d class_name = %s \n",iItr->first->variantT(),iItr->first->class_name().c_str());
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first             = %p \n",iItr->first);
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->class_name = %s \n",iItr->first->class_name().c_str());
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first->variantT() = %d \n",(int)iItr->first->variantT());
                  }
                 else
                  {
                    printf ("In querySolverGrammarElementFromVariantVector(): iItr->first == NULL \n");
                  }
#endif
               SgType* type = isSgType(iItr->first);
               if ( type != NULL  )
                  {
                 // DQ (1/13/2011): If we have not already seen this entry then we have to chase down possible nested types.
                 // if (std::find(succContainer.begin(),succContainer.end(),iItr->first) == succContainer.end() )
                    if (std::find(succContainer.begin(),succContainer.end(),type) == succContainer.end() )
                       {
                      // DQ (1/30/2010): Push the current type onto the list first, then any internal types...
                         pushNewNode (returnNodeList,targetVariantVector,type);

                      // Are there any other places where nested types can be found...?
                      // if ( isSgPointerType(iItr->first) != NULL  || isSgArrayType(iItr->first) != NULL || isSgReferenceType(iItr->first) != NULL || isSgTypedefType(iItr->first) != NULL || isSgFunctionType(iItr->first) != NULL || isSgModifierType(iItr->first) != NULL)
                      // if (type->containsInternalTypes() == true)
                         if (type->containsInternalTypes() == true)
                            {
#if 0
                              printf ("If we have not already seen this entry then we have to chase down possible nested types. \n");
                           // ROSE_ASSERT(false);
#endif

                              Rose_STL_Container<SgType*> typeVector = type->getInternalTypes();
#if 0
                              printf ("----- typeVector.size() = %zu \n",typeVector.size());
#endif
                              Rose_STL_Container<SgType*>::iterator i = typeVector.begin();
                              while(i != typeVector.end())
                                 {
#if 0
                                   printf ("----- internal type = %s \n",(*i)->class_name().c_str());
#endif
                                // DQ (1/16/2011): This causes a test in tests/roseTests/programAnalysisTests/variableLivenessTests 
                                // to fail with error "Error :: Number of nodes = 37  should be : 36"

                                // Add this type to the return list of types.
                                   pushNewNode (returnNodeList,targetVariantVector,*i);

                                   i++;
                                 }
                            }

                      // DQ (1/30/2010): Move this code to the top of the basic block.
                      // pushNewNode (returnNodeList,targetVariantVector,iItr->first);
                      // pushNewNode (returnNodeList,targetVariantVector,type);
                       }
                  }
             }
        }

#if 0
    // This code cannot be put here. Since the same SgVarRefExp will also be found during variable substitution phase.
    // We don't want to replace the original SgVarRefExp!!
    // Liao 1/19/2011. query the dim_info of SgArrayType associated with SgPntrArrRefExp
    // e.g.  assuming a subtree has a reference to an array, then the variables used to declare the array dimensions should also be treated as referenced/used by the subtree
    // even though the reference is indirect. 
    // AST should look like: 
    //    SgPntrArrRefExp -> SgVarRefExp (lhs) -> SgVariableSymbol(symbol) -> SgInitializedName -> SgArrayType (typeptr)  -> SgExprListExp (dim_info)
    // AST outlining needs to find indirect use of a variable to work properly
    if (std::find(targetVariantVector.begin(), targetVariantVector.end(), V_SgVarRefExp) != targetVariantVector.end())
    // Only do this if SgVarRefExp is of interest
    { 
      if (SgPntrArrRefExp * arr_exp = isSgPntrArrRefExp(astNode))
      {
        printf("Debug: queryVariant.C Found SgPntrArrRefExp :%p\n", arr_exp);
        Rose_STL_Container<SgNode*> refList = NodeQuery::querySubTree(arr_exp->get_lhs_operand(),V_SgVarRefExp);
        // find the array reference from the lhs operand, which could be a complex arithmetic expression
        SgVarRefExp* array_ref = NULL; 
        for (Rose_STL_Container<SgNode*>::iterator iter = refList.begin(); iter !=refList.end(); iter ++)
        {
          SgVarRefExp* cur_ref = isSgVarRefExp(*iter);
          ROSE_ASSERT (cur_ref != NULL);
          SgVariableSymbol * sym = cur_ref->get_symbol();
          ROSE_ASSERT (sym != NULL);
          SgInitializedName * i_name = sym->get_declaration();
          ROSE_ASSERT (i_name != NULL);
          SgArrayType * a_type = isSgArrayType(i_name->get_typeptr());
          if (a_type)
          {
            Rose_STL_Container<SgNode*> dim_ref_list = NodeQuery::querySubTree(a_type->get_dim_info(),V_SgVarRefExp);
            for (Rose_STL_Container<SgNode*>::iterator iter2 = dim_ref_list.begin(); iter2 != dim_ref_list.end(); iter2++)
            {
              SgVarRefExp* dim_ref = isSgVarRefExp(*iter2); 
              printf("Debug: queryVariant.C Found indirect SgVarRefExp as part of array dimension declaration:%s\n", dim_ref->get_symbol()->get_name().str());
              pushNewNode (returnNodeList, targetVariantVector, *iter2);
            }

          }  

        }
      } // end if SgPntrArrRefExp
    } // end if find()
#endif
     return NULL;
   } /* End function querySolverUnionFields() */