SynthesizedAttribute
CreateCloneDetectionVectors::evaluateSynthesizedAttribute (
     SgNode* astNode,
     SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
	 static int currentStride = 0;

     SynthesizedAttribute returnAttribute;
     //test.push_back(astNode->class_name());
     //initialize to zero
     for( int i = 0; i < V_SgNumVariants; ++i)
        {
         (returnAttribute.nodesInSubtree)[i] = 0;
        }

     nodeToCloneVector[astNode] = returnAttribute.nodesInSubtree;

     //Add current node to vector
     (returnAttribute.nodesInSubtree)[astNode->variantT()]+=1;


     //Add the vectors in the subtrees of the vector to this vector
     for(SubTreeSynthesizedAttributes::iterator iItr = synthesizedAttributeList.begin();
         iItr != synthesizedAttributeList.end(); ++iItr){
#if 0 
                for( int i = 0; i < lengthVariantT; i++)
                  {
                     std::cout << (iItr->nodesInSubtree)[i] << " " ;
            
                  }
                std::cout << std::endl << std::endl;
#endif

         returnAttribute.addToVector ( (*iItr).nodesInSubtree );
     }

     //std::cout << "\n\nVector of names" << std::endl;

#if 0	 
	 //Print out the number of elements found for each variant in the subtree
     for(int i = 0;  i < lengthVariantT; i++  ){
       if(returnAttribute.nodesInSubtree[i] > 0)
          std::cout << returnAttribute.nodesInSubtree[i] << " " << variantToName[i] << " ";
	 }
     std::cout << "\n\n";
#endif

	 //Write to the file specified in the config file on the commandline
	 if(std::find(variantToWriteToFile.begin(), variantToWriteToFile.end(), astNode->variantT()) != variantToWriteToFile.end())
	 {

	   int numTokens = 0;

	   for(unsigned int i=0; i < variantNumVec.size(); i++ )
	   {
		 numTokens+= returnAttribute.nodesInSubtree[i];
	   }


	   if( numTokens >= minTokens )
	   {

		 currentStride++;

		 //To implement the concept of a stride we need to not overcount
		 //subtrees. But I am not sure if the vectors which contains this vector
		 //should have a smaller


		 for(unsigned int i = 0;  i < variantNumVec.size(); i++  ){
		   mergedVector[i]+= returnAttribute.nodesInSubtree[i];
		 }

		 if( currentStride >= stride ){

		   VariantVector stmts(V_SgStatement);
		   VariantVector exprs(V_SgExpression);
		   VariantVector decls(V_SgDeclarationStatement);

		   int n_stmts = 0;
		   int n_exprs = 0;
		   int n_decls = 0;

		   for( VariantVector::iterator iItr = stmts.begin(); 
			   iItr != stmts.end(); ++iItr )
			 n_stmts+=stmts[*iItr];

		   for( VariantVector::iterator iItr = exprs.begin(); 
			   iItr != exprs.end(); ++iItr )
			 n_exprs+=exprs[*iItr];

		   for( VariantVector::iterator iItr = decls.begin(); 
			   iItr != decls.end(); ++iItr )
			 n_decls+=decls[*iItr];


		   myfile << "# FILE:" <<astNode->get_file_info()->get_filenameString();
		   myfile << ", LINE:" <<astNode->get_file_info()->get_line();
		   myfile << ", OFFSET:" <<astNode->get_file_info()->get_col();
		   myfile << ", NODE_KIND:" << astNode->variantT();
		   myfile << ", CONTEXT_KIND:0, NEIGHBOR_KIND:0";
           myfile << ", NUM_NODE:" << numTokens;
		   myfile << ", NUM_DECL:" << n_decls;
		   myfile << ", NUM_STMT:" << n_stmts;
		   myfile << ", NUM_EXPR:" << n_exprs;
		   myfile << ", TBID:0, TEID:0, VARs:{}0,"; 
		   myfile << std::endl;

		   for(unsigned int i = 0;  i < variantNumVec.size(); i++  ){
			 myfile << mergedVector[i] << " ";

			 //std::cout << returnAttribute.nodesInSubtree[variantNumVec[i]] << " " << roseGlobalVariantNameList[variantNumVec[i]] << " ";
		   }
		   myfile << std::endl;

		   currentStride = 0;

		   for(unsigned int i = 0;  i < variantNumVec.size(); i++  ){
			 mergedVector[i] = 0;
		   }


		 }
	   }

	 }

     return returnAttribute;
   }
Example #2
0
DOTSynthesizedAttribute
AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l)
   {
     SubTreeSynthesizedAttributes::iterator iter;
     ROSE_ASSERT(node);

  // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str());

  // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute
     if (ia.skipSubTree == true)
        {
       // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute
       // Figured this out: if we return a valid pointer then we get a node in the DOT graph 
       // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute 
       // with a NUL pointer then the node will NOT appear in the DOT graph.
       // return DOTSynthesizedAttribute(node);
          return DOTSynthesizedAttribute(NULL);
        }

     string nodeoption;
     if(AstTests::isProblematic(node))
        {
       // cout << "problematic node found." << endl;
          nodeoption="color=\"orange\" ";
        }
     string nodelabel=string("\\n")+node->class_name();

  // DQ (1/24/2009): Added support for output of isForward flag in the dot graph.
     SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node);
     if (genericDeclaration != NULL)
        {
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
          string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward";
          ROSE_ASSERT(name.empty() == false);

       // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST.
          SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration);
          if (classDeclaration != NULL)
             {
               nodelabel += string("\\n") + classDeclaration->get_name();
             }

       // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration);
          if (functionDeclaration != NULL)
             {
               nodelabel += string("\\n") + functionDeclaration->get_name();
             }

          nodelabel += string("\\n") + name;
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgInitializedName* initializedName = isSgInitializedName(node);
     if (initializedName != NULL)
        {
          nodelabel += string("\\n") + initializedName->get_name();
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgIntVal* intValue = isSgIntVal(node);
     if (intValue != NULL)
        {
          nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value());
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgVarRefExp* varRefExp = isSgVarRefExp(node);
     if (varRefExp != NULL)
        {
          SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
          ROSE_ASSERT(variableSymbol != NULL);
          string name = variableSymbol->get_name();
          nodelabel += string("\\n name = ") + name;
        }

  // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph.
     SgAsmInstruction* genericInstruction = isSgAsmInstruction(node);
     if (genericInstruction != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
#if 1
          string unparsedInstruction = unparseInstruction(genericInstruction);
          string addressString       = StringUtility::numberToString( (void*) genericInstruction->get_address() );
       // string name = genericInstruction->get_mnemonic();
          string name = unparsedInstruction + "\\n address: " + addressString;
#else
          string name = unparsedInstruction + "\\n" + addressString;
#endif
          ROSE_ASSERT(name.empty() == false);

          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

     SgAsmExpression* genericExpression = isSgAsmExpression(node);
     if (genericExpression != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
          string name = unparseExpression(genericExpression, NULL, NULL);
          ROSE_ASSERT(name.empty() == false);
          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes.
  // In generall there are long list of these IR nodes in the binary and this helps make some sense of 
  // the lists (sections, symbols, etc.).
     SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node);
     if (binaryFileFormatNode != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // The case of binary file format IR nodes can be especially confusing so we want the 
       // default to output some more specific information for some IR nodes (e.g. sections).
          string name;

          SgAsmGenericSection* genericSection = isSgAsmGenericSection(node);
          if (genericSection != NULL)
             {
               SgAsmGenericString* genericString = genericSection->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node);
          if (genericSymbol != NULL)
             {
               SgAsmGenericString* genericString = genericSymbol->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();

               if (name.empty() == true)
                    name = "no_name_for_symbol";
             }

          SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node);
          if (genericDLL != NULL)
             {
               SgAsmGenericString* genericString = genericDLL->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node);
          if (peImportItem != NULL)
             {
               SgAsmGenericString* genericString = peImportItem->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node);
          if (asmDwarfLine != NULL)
             {
               char buffer[100];

            // It does not work to embed the "\n" into the single sprintf parameter.
            // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column());

               sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address());
               name = buffer;
               sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column());
               name += string("\\n") + buffer;
             }

          SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node);
          if (asmDwarfConstruct != NULL)
             {
               name = asmDwarfConstruct->get_name();
             }

#if 0
       // This might not be the best way to implement this, since we want to detect common base classes of IR nodes.
          switch (node->variantT())
             {
               case V_SgAsmElfSection:
                  {
                    SgAsmElfSection* n = isSgAsmElfSection(node);
                    name = n->get_name();
                    break;
                  }

               default:
                  {
                 // No additional information is suggested for the default case!
                  }
             }
#endif

          if (name.empty() == false)
               nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (11/29/2008): Output the directives in the label of the IR node.
     SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node);
     if (preprocessorDirective != NULL)
        {
          string s = preprocessorDirective->get_directiveString();

       // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables.
          while (s.find("\"") != string::npos)
             {
               s.replace(s.find("\""),1,"\'");
             }

          if (s.empty() == false)
               nodelabel += string("\\n") + s;
        }

     nodelabel += additionalNodeInfo(node);

  // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.)
  // nodeoption += additionalNodeOptions(node);
     string additionalOptions = additionalNodeOptions(node);
  // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size());
  // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size());

     string x;
     string y;
     x += additionalOptions;

     nodeoption += additionalOptions;

     DOTSynthesizedAttribute d(0);

  // DQ (7/27/2008): Added mechanism to support pruning of AST
     bool commentoutNode = commentOutNodeInGraph(node);
     if (commentoutNode == true)
        {
       // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option.
       // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file.
          if (SgProject::get_verbose() > 0)
             {
               printf ("Skipping the use of this IR node in the DOT Graph \n");
             }
        }
       else
        {

// **************************

     switch(traversal)
        {
          case TOPDOWNBOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption);
               break;
          case PREORDER:
          case TOPDOWN:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
               break;
          case POSTORDER:
          case BOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption);
               break;
          default:
               assert(false);
        }
  
     ++tdbuTrace;
     ++buTrace;

  // add edges or null values
     int testnum=0;
     for (iter = l.begin(); iter != l.end(); iter++)
        {
          string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]);
          string toErasePrefix = "p_";

          if (AstTests::isPrefix(toErasePrefix,edgelabel))
             {
               edgelabel.erase(0, toErasePrefix.size());
             }

          if ( iter->node == NULL)
             {
            // SgNode* snode=node->get_traversalSuccessorContainer()[testnum];
               AstSuccessorsSelectors::SuccessorsContainer c;
               AstSuccessorsSelectors::selectDefaultSuccessors(node,c);
               SgNode* snode=c[testnum];

            // isDefault shows that the default constructor for synth attribute was used
               if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) )
                  {
                 // handle bugs in SAGE
                    dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red ");
                  }
                 else
                  {
                    if (snode == NULL)
                       {
                         dotrep.addNullValue(node,"",edgelabel,"");
                       }
                  }
             }
            else
             {
            // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.)
               string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel);

               switch(traversal)
                  {
                    case TOPDOWNBOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both");
                         break;
                    case PREORDER:
                    case TOPDOWN:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward");
                         break;
                    case POSTORDER:
                    case BOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back");
                         break;
                    default:
                         assert(false);
                  }
             }

          testnum++;
        }

// **************************
        }



  // DQ (7/4/2008): Support for edges specified in AST attributes
     AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism();
     if (astAttributeContainer != NULL)
        {
       // Loop over all the attributes at this IR node
          for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++)
             {
            // std::string name = i->first;
               AstAttribute* attribute = i->second;
               ROSE_ASSERT(attribute != NULL);

            // This can return a non-empty list in user-defined attributes (derived from AstAttribute).
            // printf ("Calling attribute->additionalNodeInfo() \n");
               std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo();
            // printf ("nodeList.size() = %lu \n",nodeList.size());

               for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++)
                  {
                    SgNode* nodePtr   = i_node->nodePtr;
                    string nodelabel  = i_node->label;
                    string nodeoption = i_node->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str());
                 // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
                    dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption );
                  }

            // printf ("Calling attribute->additionalEdgeInfo() \n");
               std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo();
            // printf ("edgeList.size() = %lu \n",edgeList.size());
               for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++)
                  {
                    string edgelabel  = i_edge->label;
                    string edgeoption = i_edge->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str());
                    dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward");
                  }
             }
        }



     switch(node->variantT())
        {
       // DQ (9/1/2008): Added case for output of SgProject rooted DOT file.
       // This allows source code and binary files to be combined into the same DOT file.
          case V_SgProject: 
             {
               SgProject* project = dynamic_cast<SgProject*>(node);
               ROSE_ASSERT(project != NULL);

               string generatedProjectName = SageInterface::generateProjectName( project );
            // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
               if (generatedProjectName.length() > 40)
                  {
                 // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
                    generatedProjectName = "aggregatedFileNameTooLong";
                    printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str());
                  }

               string filename = string("./") + generatedProjectName + ".dot";

            // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str());
               if ( SgProject::get_verbose() >= 1 )
                    printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str());

               dotrep.writeToFileAsGraph(filename);
               break;
             }

       // case V_SgFile: 
          case V_SgSourceFile: 
          case V_SgBinaryComposite: 
             {
               SgFile* file = dynamic_cast<SgFile*>(node);
               ROSE_ASSERT(file != NULL);

               string original_filename = file->getFileName();

            // DQ (7/4/2008): Fix filenamePostfix to go before the "."
            // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot";
               string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot";

            // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent());

            // printf ("file->get_parent() = %p \n",file->get_parent());
            // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... ";

            // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified 
            // on the command line.  A SgProject is still built even when a single file is specificed 
            // on the command line, however there are cases where a SgFile can be built without a 
            // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files.
            // If there is a SgProject then output the dot file from there, else output as a SgFile.
               if (file->get_parent() == NULL)
                  {
                 // If there is no SgProject then output the file now!
                    if ( SgProject::get_verbose() >= 1 )
                         printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n");

                    dotrep.writeToFileAsGraph(filename);
                  }
                 else
                  {
                 // There is a SgProject IR node, but if we will be traversing it we want to output the 
                 // graph then (so that the graph will include the SgProject IR nodes and connect multiple 
                 // files (SgSourceFile or SgBinaryComposite IR nodes).
                    if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() )
                       {
                      // This SgProject node was not input as part of the traversal, 
                      // so we will not be traversing the SgProject IR nodes and we 
                      // have to output the graph now!

                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n");

                         dotrep.writeToFileAsGraph(filename);
                       }
                      else
                       {
                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n");
                       }
                  }
               
            // cout << "done." << endl;
               break;
             }

       // DQ (7/23/2005): Implemented default case to avoid g++ warnings 
       // about enum values not handled by this switch
          default: 
             {
            // nothing to do here
               break;
             }
        }

     d.node = node;
     return d;
   }
        adRecord evaluateSynthesizedAttribute (SgNode* n, aiRecord inherited, 
                                               SubTreeSynthesizedAttributes synthesized )
        {
                //printf("evaluateSynthesizedAttribute(n=%p)\n");
                adRecord dr(n);
                SgPntrArrRefExp* arrRef;
                
                if((arrRef = isSgPntrArrRefExp(n)))
                {
                        //printf("evaluateSynthesizedAttribute() arrRef->lhs=%p, arrRef->rhs=%p\n", arrRef->get_lhs_operand(), );
                        bool found=false;
                        // look through both the synthesized attributes 
                        // (one from the SgPntrArrRefExp's array name subtree and one from the index subtree)
                        
                        // get the name subtree
                        for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++)
                        {
                                // if this synthesized attribute comes from SgPntrArrRefExp's array name subtree
                                // (there should be only one such subtree)
                                if((*it).origin == arrRef->get_lhs_operand())
                                {
                                        // copy over the info from the name subtree
                                        found = true;
                                        dr.arrayDim=(*it).arrayDim+1;
                                        // if the array name expression hasn't been found yet, this 
                                        // SgPntrArrRefExp's array name subtree must be it
                                        if((*it).arrayNameExp==NULL)
                                                dr.arrayNameExp = arrRef->get_lhs_operand();
                                        // otherwise, the real array name expression is deeper in the array name subtree, so just copy it over
                                        else
                                                dr.arrayNameExp = (*it).arrayNameExp;
                                        
                                        // initialize this SgPntrArrRefExp's list of indexes from the lower-level list
                                        dr.indexExprs = (*it).indexExprs;
//                                      break;
                                }
                        }
                        ROSE_ASSERT(found);
                        
                        found = false;
                        // get the index subtree
                        for(SubTreeSynthesizedAttributes::iterator it=synthesized.begin(); it!=synthesized.end(); it++)
                        {
                                // if this synthesized attribute comes from SgPntrArrRefExp's index subtree
                                // (there should be only one such subtree)
                                if((*it).origin == arrRef->get_rhs_operand())
                                {
                                        found = true;
                                        // add the current index expression to this SgPntrArrRefExp's list of indexes
                                        dr.indexExprs.push_front(isSgExpression((*it).origin));
                                }
                        }
                        ROSE_ASSERT(found);
                }
                
/*              if(isSgPntrArrRefExp(n))
                        printf("SgPntrArrRefExp:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim);
                else
                        printf("SgNode:0x%x UP arrayIndexFlag=%d arrayNameExp=0x%x arrayDim=%d\n", n, dr.arrayIndexFlag, dr.arrayNameExp, dr.arrayDim);
                printf("         <%s>\n", n->unparseToString().c_str());*/
                                
                // label this node with its read/write access information
                arrIndexAttribute* aiAttr = new arrIndexAttribute(dr);
                char attrName[100];
                sprintf(attrName, "ArrayIndex: [%d, %d, %p, %d]", dr.arrayIndexFlag, dr.topArrayRefExpFlag, dr.arrayNameExp, dr.arrayDim);
                n->addNewAttribute(attrName, aiAttr);
                n->updateAttribute("ArrayIndex", aiAttr);
                
                return dr;
        }
Example #4
0
// void RemoveConstantFoldedValue::visit ( SgNode* node )
RemoveConstantFoldedValueSynthesizedAttribute
RemoveConstantFoldedValue::evaluateSynthesizedAttribute ( SgNode* node, SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     ROSE_ASSERT(node != NULL);

  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
#if 0
#if 0
  // Avoid excessive output.
     if (isSgFunctionDeclaration(node) == NULL && isSgInitializedName(node) == NULL && isSgFunctionParameterList(node) == NULL)
          printf ("In RemoveConstantFoldedValue::evaluateSynthesizedAttribute(): node = %p = %s synthesizedAttributeList.size() = %" PRIuPTR " \n",node,node->class_name().c_str(),synthesizedAttributeList.size());
#else
     printf ("In RemoveConstantFoldedValue::evaluateSynthesizedAttribute(): node = %p = %s synthesizedAttributeList.size() = %" PRIuPTR " \n",node,node->class_name().c_str(),synthesizedAttributeList.size());
#endif
#endif

  // Here we reset the pointer to the constant folded value to be the pointer to the original expression tree.
     SubTreeSynthesizedAttributes::iterator i = synthesizedAttributeList.begin();
     while (i != synthesizedAttributeList.end())
        {
#if 0
       // Avoid excessive output.
          if (isSgFunctionDeclaration(i->node) == NULL && isSgInitializedName(i->node) == NULL && isSgFunctionParameterList(i->node) == NULL && i->node != NULL)
               printf ("synthesizedAttribute = %p = %s \n",i->node,(i->node != NULL) ? i->node->class_name().c_str() : "NULL");
#endif

       // DQ (10/8/2011): Refectored this code so that we could better support chains of original expression trees (see test2011_146.C).
          handleTheSynthesizedAttribute(node,*i);

          i++;
        }

  // Here we force the nested traversal of the originalExpressionTree, since it is not traversed as part of the AST.
  // Note that these are not always leaf nodes that we want to interogate (see test2011_140.C).

  // DQ (9/24/2011): I think this is the wrong place to process this case (see test2011_140.C).
  // DQ (9/24/2011): We have fixed the AST traversal to no longer traverse originalExpressionTree subtree's (since 
  // it make analysis using the traversal redundant with the constant folded values).
  // If the current node is an expression and a leaf node of the AST, then check if it has an originalExpressionTree, 
  // since we no longer traverse the originalExpressionTree as part of the definition of the AST.
  // SgExpression* leafExpression = (synthesizedAttributeList.empty() == true) ? isSgExpression(node) : NULL;
     SgExpression* expression = isSgExpression(node);
     if (expression != NULL)
        {
#if 0
          printf ("In RemoveConstantFoldedValue::evaluateSynthesizedAttribute(): Found an expression \n");
#endif
          SgExpression* originalExpressionTree = expression->get_originalExpressionTree();
          if (originalExpressionTree != NULL)
             {
#if 0
               printf ("Found an expression with a valid originalExpressionTree\n");
#endif
            // Make sure that the traversal will see the nested subtrees of any originalExpressionTree (since they may have constant folded subexpresions).
               RemoveConstantFoldedValue nestedOriginalExpressionTreeTraversal;
               RemoveConstantFoldedValueSynthesizedAttribute nestedSynthesizedAttribute = nestedOriginalExpressionTreeTraversal.traverse(originalExpressionTree);
#if 0
            // DQ (10/8/2011): We should not handl this here, I think.
               handleTheSynthesizedAttribute(node,nestedSynthesizedAttribute);
#endif
#if 0
               printf ("DONE: Found an expression with a valid originalExpressionTree nestedSynthesizedAttribute \n");
#endif
             }
        }

     return RemoveConstantFoldedValueSynthesizedAttribute(node);
   }
Example #5
0
Detection_SynthesizedAttribute
DetectionTraversal::evaluateSynthesizedAttribute (SgNode* astNode, Detection_InheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     ROSE_ASSERT(astNode != NULL);

     Detection_SynthesizedAttribute return_synthesizedAttribute(astNode);

#if 1
     printf ("In evaluateSynthesizedAttribute(): astNode = %p = %s synthesizedAttributeList.size() = %zu dslChildren.size() = %zu \n",
          astNode,astNode->class_name().c_str(),synthesizedAttributeList.size(),return_synthesizedAttribute.dslChildren.size());
#endif

  // At each IR node and across all children, accumulate the dslChildren (child nodes for each of the DSL AST nodes).
     for (SubTreeSynthesizedAttributes::iterator i = synthesizedAttributeList.begin(); i != synthesizedAttributeList.end(); i++)
        {
          SgNode* childNode = (*i).node;
       // ROSE_ASSERT(childNode != NULL);
          if (childNode != NULL)
             {
#if 0
               printf ("Identified child node in evaluateSynthesizedAttribute(): childNode = %p = %s \n",childNode,childNode->class_name().c_str());
#endif
            // Insert each list from the child into the accumulated list in the current Synthesized Attribute.
               return_synthesizedAttribute.dslChildren.insert(return_synthesizedAttribute.dslChildren.end(),i->dslChildren.begin(),i->dslChildren.end());
#if 0
               printf ("   --- copying i->dslChildren.size() = %zu into return_synthesizedAttribute.dslChildren.size() = %zu \n",i->dslChildren.size(),return_synthesizedAttribute.dslChildren.size());
#endif
               if (return_synthesizedAttribute.dslChildren.empty() == false)
                  {
#if 0
                    printf ("In evaluateSynthesizedAttribute(): dslChildren.size() = %zu \n",return_synthesizedAttribute.dslChildren.size());
#endif
                  }
             }
            else
             {
#if 1
               printf ("childNode == NULL \n");
#endif
             }
        }


  // Recognition of other control statements (e.g. for loops for the stencil evaluation) or expression/statement abstractions (e.g. function calls)
  // Note: DSL specific control abstractions might be recognised as loops containing DSL abstractions and having constant evaluatable base and bounds.


  // For any DSL specific AST nodes (C++ AST nodes containing a DSL_Attribute), initialize the pointers to children of the DSL IR node.
     AstAttributeMechanism* astAttributeContainer = astNode->get_attributeMechanism();
     if (astAttributeContainer != NULL)
        {
#if 1
          printf ("In evaluateSynthesizedAttribute(): found a attribute on astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif
       // I think there should only be one DSL attribute, in the future we can support more on a single IR node.
          if (astAttributeContainer->size() != 1)
             {
               printf ("WARNING: astAttributeContainer->size() != 1: astAttributeContainer->size() = %zu \n",astAttributeContainer->size());
             }
#if 1
       // DQ: Allow this for the moment while testing.
          ROSE_ASSERT(astAttributeContainer->size() == 1);
#endif
       // Loop over all the attributes at this IR node
       // Pei-Hung (12/22/15): THe ASTAttributeMechanmsim is changed and has to use new API
       // for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++)
          BOOST_FOREACH (const std::string &attributeName, astAttributeContainer->getAttributeIdentifiers()) 
             {
               AstAttribute* attribute = astNode->getAttribute(attributeName);
               ROSE_ASSERT(attribute != NULL);
#if 1
            // DSL_Attribute* dslAstAttribute = dynamic_cast<DSL_Attribute*>(attribute);
               dsl_attribute* dslAstAttribute = dynamic_cast<dsl_attribute*>(attribute);
               ROSE_ASSERT(dslAstAttribute != NULL);
#if 1
               printf ("Identified dslAstAttribute in evaluateSynthesizedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
               printf ("   --- return_synthesizedAttribute.dslChildren.size() = %zu \n",return_synthesizedAttribute.dslChildren.size());
#endif
            // Copy the dsl child data to the dsl attribute.
               dslAstAttribute->currentNode = astNode;
               dslAstAttribute->dslChildren = return_synthesizedAttribute.dslChildren;
#endif
             }

       // Clear the dsl attributes becasue we the only collect dsl child attributes at dsl attributed IR nodes and don't pass then further up the tree.          
          return_synthesizedAttribute.dslChildren.clear();

       // Add the current node since it has an attribute.
          return_synthesizedAttribute.dslChildren.push_back(astNode);

#if 0
          printf ("Exiting as a test! \n");
          ROSE_ASSERT(false);
#endif
        }
MySynthesizedAttribute
MyTraversal::evaluateRewriteSynthesizedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute,
		SubTreeSynthesizedAttributes synthesizedAttributeList )
{
	MySynthesizedAttribute returnAttribute;

	switch(astNode->variantT())
	{

		case V_SgVarRefExp: {
				cout << " found V_SgVarRefExp " << astNode->unparseToString() <<  endl;
				if(mReplaceVariable) {
					if( ( strcmp( astNode->unparseToString().c_str(), VARIABLE_NAME )==0 ) &&
							( isSgTypeInt(isSgVarRefExp(astNode)->get_type()) )
						) {
						returnAttribute.setVarRefFound( true );
						AstRestructure::unparserReplace( isSgVarRefExp(astNode), "newInt" );
						cout << "   replacing with 'newInt' " << endl;
					}
				}
			} break;

		case V_SgVariableDeclaration: {
				SgVariableDeclaration *varDecl = isSgVariableDeclaration(astNode);
				cout << " found V_SgVariableDeclaration " << astNode->unparseToString() <<  endl;
				// replace only integer variables called "i"
				if( (varDecl->get_traversalSuccessorContainer().size() > 0) &&
                                    isSgInitializedName( varDecl->get_traversalSuccessorContainer()[0]) && 
                                                ( strcmp(isSgInitializedName(varDecl->get_traversalSuccessorContainer()[0])->get_name().str(), VARIABLE_NAME )==0 ) &&
						( isSgTypeInt(isSgInitializedName(varDecl->get_traversalSuccessorContainer()[0])->get_type()) )
					) {
					// found declaration of "int i"
					string newDeclaration("int newInt = i + 100;");
					returnAttribute.insert( varDecl, newDeclaration, HighLevelCollectionTypedefs::LocalScope, HighLevelCollectionTypedefs::AfterCurrentPosition );
					assert( mReplaceVariable==0 ); // if it's true, there is another "int i", and this transformation wont work...
					mReplaceVariable = 1;
					cout << "   inserted: '" << newDeclaration <<"' , starting variable replacement " <<  endl;
				}
			} break;

		default:
			break;
	} // node type

	bool synth = false;
	for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin();
             i!= synthesizedAttributeList.end(); i++ ) {
                if( (*i).getVarRefFound() ) synth = true;
	}
	if( synth ) {
		returnAttribute.setVarRefFound( true );
		if(isSgStatement( astNode )) {
			cout << "   new statement " << " : '" << astNode->unparseToString() << "' " << endl;
			returnAttribute.setVarRefFound( false );
			//if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!?
				returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope );
			//}
		}
	}

	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable--;
			cerr << "end of scope " << mReplaceVariable << endl;
		}
	} 

	return returnAttribute;
}
MySynthesizedAttribute
MyTraversal::evaluateRewriteSynthesizedAttribute (
		SgNode* astNode,
		MyInheritedAttribute inheritedAttribute,
		SubTreeSynthesizedAttributes synthesizedAttributeList )
{
	MySynthesizedAttribute returnAttribute;

	
	switch(astNode->variantT())
	{

		case V_SgForStatement: {
				SgForStatement *forStat = isSgForStatement(astNode); 
				cout << " found V_SgForStatement " << printPosition(astNode) << "" <<  endl;
				for(size_t i=0; i<mAllFors.size(); i++) {
					if((mAllFors[i]->blocked)&&(astNode == mAllFors[i]->forStmt)) {
						ostringstream newFor;
						newFor << "for(";
						newFor << (*(forStat->get_init_stmt().begin()))->unparseToString();
						newFor << forStat->get_test_expr()->unparseToString() << ";" ;
						newFor << mAllFors[i]->varName << "+=" << mAllFors[i]->blockSize << ")\n" ;
						newFor << forStat->get_loop_body()->unparseToString();
						cout << " is blocked loop..." << endl;
						returnAttribute.replace( astNode, newFor.str() );
					}
				}
			} break;

		case V_SgVarRefExp: {
				cout << " found V_SgVarRefExp " << printPosition(astNode) << astNode->unparseToString() <<  endl;
				forBlockVector fors = inheritedAttribute.getForScopes();

				// replace variable occurrences in the loop kernel
				if(inheritedAttribute.getLoopKernel()) {
					for(size_t i=0;i<fors.size(); i++) {
						if( ( strcmp( astNode->unparseToString().c_str(), fors[i]->varName.c_str() )==0 ) &&
								( isSgVarRefExp(astNode)->get_type() == fors[i]->varType )
							) {
							string blockedVarName("blocked_");
							blockedVarName += fors[i]->varName;
							AstRestructure::unparserReplace( isSgVarRefExp(astNode), blockedVarName );
							cout << "   replacing with '"<<blockedVarName<<"' " << endl;
						}
					}
				}
			} break;

		default:
			break;
	} // node type

	bool synth = false;
	for( SubTreeSynthesizedAttributes::iterator i=synthesizedAttributeList.begin();
             i!= synthesizedAttributeList.end(); i++ ) {
                if( (*i).getVarRefFound() ) synth = true;
	}
	if( synth ) {
		returnAttribute.setVarRefFound( true );
		if(isSgStatement( astNode )) {
			cout << "   new statement " << printPosition(astNode) << " : '" << astNode->unparseToString() << "' " << endl;
			returnAttribute.setVarRefFound( false );
			//if(!isSgReturnStmt( astNode )) { // DEBUG, this should work!??!?
			returnAttribute.replace( astNode, astNode->unparseToString(), HighLevelCollectionTypedefs::LocalScope );
			//}
		}
	}

	if(isSgScopeStatement(astNode)) {
		// dont replace variable in higher scopes...
		if(mReplaceVariable > 0) {
			mReplaceVariable--;
			cerr << "end of scope " << mReplaceVariable << endl;
		}
	} 

	//if(astNode == mpLoopBody) { // FIXME why doesnt replace basic block work?
	if( (astNode->get_parent() == mpLoopBody)&&(inheritedAttribute.getLoopKernel()) ) {
		// we're back at the loop kernel block, now replace and insert new loops...
		insertTransformedLoopBody( astNode, returnAttribute, inheritedAttribute.getForScopes() );
	}

	return returnAttribute;
}