Ejemplo n.º 1
0
bool
ReplacementMapTraversal::verifyODR( SgNode* node, SgNode* duplicateNodeFromOriginalAST )
   {
     bool passesODR = false;
  // printf ("Verify that node = %p is equivalent to duplicateNodeFromOriginalAST = %p = %s \n",node,duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str());

  // Verify that these strings match
     ROSE_ASSERT (duplicateNodeFromOriginalAST->variantT() == node->variantT());
     ROSE_ASSERT (duplicateNodeFromOriginalAST->class_name() == node->class_name());
  // ROSE_ASSERT (generateUniqueName(duplicateNodeFromOriginalAST) == generateUniqueName(node));

     string nodeString;
     string duplicateNodeFromOriginalASTstring;

#if 0
  // DQ (2/3/2007): This is a test to debug the ODR checking.
  // I think that the unparser has some state specific to the output of access protections.
  // if the unparsing changes the state then the access permission (public, protected, private) 
  // is output and this cause a falue trigger to the ODR string match.  This is a temp fix to
  // absorbe any change of state, but we need a mechanism to clear the state in the unparser.
     string absorbeUnparserStateChange_A = node->unparseToString();
     string absorbeUnparserStateChange_B = duplicateNodeFromOriginalAST->unparseToString();
#endif
#if 0
  // DQ (2/3/2007): Make sure that there are close to being related. It appears that if these are
     if (node->get_parent()->variantT() == duplicateNodeFromOriginalAST->get_parent()->variantT())
        {
          nodeString                         = node->unparseToString();
          duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString();
        }
#endif

     bool skip_ODR_test = false;

     bool nodeIsCompilerGenerated = 
          (node->get_file_info() != NULL) ? node->get_file_info()->isCompilerGenerated() : false;
     bool duplicateNodeFromOriginalASTIsCompilerGenerated = 
          (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isCompilerGenerated() : false;

     bool nodeIsFrontendSpecific = 
          (node->get_file_info() != NULL) ? node->get_file_info()->isFrontendSpecific() : false;
     bool duplicateNodeFromOriginalASTIsFrontendSpecific = 
          (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isFrontendSpecific() : false;

  // If this is a template declaration for a function then it might have been a part of another template declaration 
  // for the template class and thus might not exist explicitly in the AST (and thus not have enough information from 
  // which to generate a meaningful mangled name).  Skip ODR testing of these cases.
     bool isTemplateMemberFunctionInTemplatedClass = false;
     SgTemplateDeclaration* templateDeclaration = isSgTemplateDeclaration(node);
     if (templateDeclaration != NULL)
        {
          SgTemplateDeclaration* dup_templateDeclaration = isSgTemplateDeclaration(duplicateNodeFromOriginalAST);
          ROSE_ASSERT(dup_templateDeclaration != NULL);
          if ( templateDeclaration->get_string().is_null() && dup_templateDeclaration->get_string().is_null() )
             {
               isTemplateMemberFunctionInTemplatedClass = true;
             }
        }

     if (isTemplateMemberFunctionInTemplatedClass == true)
        {
          printf ("ODR not tested isTemplateMemberFunctionInTemplatedClass == true. \n");
          skip_ODR_test = true;
        }

     if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true || nodeIsCompilerGenerated == true || duplicateNodeFromOriginalASTIsCompilerGenerated == true)
        {
       // printf ("ODR not tested for frontend specific compiler generated code. \n");
          skip_ODR_test = true;
        }

  // DQ (1/20/2007): The unparse will not generate a string if the code is frontend specific or compiler generated (I forget which).
  // if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true)
     if (skip_ODR_test == true)
        {
       // printf ("ODR not tested for frontend specific compiler generated code. \n");
          passesODR = true;
        }
       else
        {
          SgUnparse_Info info_a;
          SgUnparse_Info info_b;

       // DQ (2/6/2007): Force qualified names to be used uniformally (note that info.set_requiresGlobalNameQualification() 
       // causes an error) info.set_requiresGlobalNameQualification();
          info_a.set_forceQualifiedNames();
          info_b.set_forceQualifiedNames();

          nodeString                         = node->unparseToString(&info_a);

       // DQ (2/6/2007): The SgUnparse_Info object carries state which controls the use of access qualification and the 
       // first call to unparseToString might have set the access (e.g. to "public") and the second call would drop the 
       // access qualification.  We unset the access qualification state in the SgUnparse_Info object so that both will 
       // be unparsed the same (we could have alternatively used two separate SgUnparse_Info objects.
       // info.set_isUnsetAccess();

          duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString(&info_b);

          passesODR = (nodeString == duplicateNodeFromOriginalASTstring);
        }

  // Don't count the cases where the unparse fails to to invalid parent in redundant SgClassDeclaration (fix these later)
     if (passesODR == false && nodeString.empty() == false && duplicateNodeFromOriginalASTstring.empty() == false)
        {
#if 1
          if (SgProject::get_verbose() > 0)
               printf ("##### In ReplacementMapTraversal::verifyODR() is false: node = %p = %s duplicateNodeFromOriginalAST = %p = %s \n",
                    node,node->class_name().c_str(),duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str());

       // printf ("##### passesODR = %s \n",passesODR ? "true" : "false");
       // printf ("duplicateNodeFromOriginalASTstring = \n---> %s\n",duplicateNodeFromOriginalASTstring.c_str());
       // printf ("nodeString                         = \n---> %s\n",nodeString.c_str());
          if (node->get_file_info() != NULL && duplicateNodeFromOriginalAST->get_file_info() != NULL)
             {
               if (SgProject::get_verbose() > 0)
                  {
                    SgNode* parent_node = node->get_parent();

                 // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code.
                    ROSE_ASSERT(parent_node != NULL);

                    printf ("parent_node = %p = %s = %s \n",parent_node,parent_node->class_name().c_str(),SageInterface::get_name(parent_node).c_str());
                    SgNode* parent_dup = duplicateNodeFromOriginalAST->get_parent();

                 // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code.
                    ROSE_ASSERT(parent_dup != NULL);

                    printf ("parent_dup = %p = %s = %s \n",parent_dup,parent_dup->class_name().c_str(),SageInterface::get_name(parent_dup).c_str());

                    printf ("\nPosition of error: \n");
                    node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug");
                    duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug");
                    printf ("\nPosition of error: \n");

                    printf ("\nPosition of error (parent IR node): \n");
                    parent_node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_node) is false: debug");
                    parent_dup->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_dup) is false: debug");
                    printf ("\nPosition of error (parent IR node): \n");
                  }
             }
            else
             {
               SgClassType* classType = isSgClassType(node);
               SgClassType* duplicateNodeFromOriginalAST_classType = isSgClassType(duplicateNodeFromOriginalAST);
               if (classType != NULL)
                  {
                    if (SgProject::get_verbose() > 0)
                       {
                         SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration());
                         ROSE_ASSERT(classDeclaration != NULL);
                         classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (classType)");
                         printf ("classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n",
                              classDeclaration,
                              classDeclaration->get_definingDeclaration(),
                              classDeclaration->get_firstNondefiningDeclaration());

                         ROSE_ASSERT(duplicateNodeFromOriginalAST_classType != NULL);
                         SgClassDeclaration* duplicateNodeFromOriginalAST_classDeclaration = isSgClassDeclaration(duplicateNodeFromOriginalAST_classType->get_declaration());
                         ROSE_ASSERT(duplicateNodeFromOriginalAST_classDeclaration != NULL);
                         duplicateNodeFromOriginalAST_classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (duplicateNodeFromOriginalAST_classType)");
                         printf ("duplicateNodeFromOriginalAST_classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n",
                              duplicateNodeFromOriginalAST_classDeclaration,
                              duplicateNodeFromOriginalAST_classDeclaration->get_definingDeclaration(),
                              duplicateNodeFromOriginalAST_classDeclaration->get_firstNondefiningDeclaration());
                       }
                  }
             }
#endif
          odrViolations.push_back(pair<SgNode*,SgNode*>(node,duplicateNodeFromOriginalAST));
        }
#if 0
     printf ("duplicateNodeFromOriginalASTstring = %p = %s \n---> %s\n",
          duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),duplicateNodeFromOriginalASTstring.c_str());
     printf ("nodeString                         = %p = %s \n---> %s\n",
          node,node->class_name().c_str(),nodeString.c_str());
#endif
#if 0
     SgClassType* original = isSgClassType(duplicateNodeFromOriginalAST);
     SgClassType* target   = isSgClassType(node);
     if (original != NULL && target != NULL)
        {
          printf ("original declaration = %p \n",original->get_declaration());
          printf ("target declaration   = %p \n",target->get_declaration());
        }
#endif
#if 1
     if (passesODR == false)
        {
          if (SgProject::get_verbose() > 0)
             {
               string node_generatedName         = SageInterface::generateUniqueName(node,false);
               string originalNode_generatedName = SageInterface::generateUniqueName(duplicateNodeFromOriginalAST,false);

               printf ("ODR Violation Source code: nodeString                         = \n%s\n \n",nodeString.c_str());
               printf ("ODR Violation Source code: duplicateNodeFromOriginalASTstring = \n%s\n \n",duplicateNodeFromOriginalASTstring.c_str());
               printf ("nodeString = %s \n",nodeString.c_str());
               printf ("node_generatedName         = %s \n",node_generatedName.c_str());
               printf ("originalNode_generatedName = %s \n",originalNode_generatedName.c_str());

               printf ("node                         = %p = %s = %s \n",node,node->class_name().c_str(),SageInterface::get_name(node).c_str());
               printf ("duplicateNodeFromOriginalAST = %p = %s = %s \n",duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),SageInterface::get_name(duplicateNodeFromOriginalAST).c_str());

               printf ("node (unique string)                         = %s \n",generateUniqueName(node,true).c_str());
               printf ("duplicateNodeFromOriginalAST (unique string) = %s \n",generateUniqueName(duplicateNodeFromOriginalAST,true).c_str());

               SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(node);
               if (declarationStatement != NULL)
                  {
                    printf ("declarationStatement->get_definingDeclaration()         = %p \n",declarationStatement->get_definingDeclaration());
                    printf ("declarationStatement->get_firstNondefiningDeclaration() = %p \n",declarationStatement->get_firstNondefiningDeclaration());
                  }

               SgDeclarationStatement* declarationStatement2 = isSgDeclarationStatement(duplicateNodeFromOriginalAST);
               if (declarationStatement2 != NULL)
                  {
                    printf ("declarationStatement2->get_definingDeclaration()         = %p \n",declarationStatement2->get_definingDeclaration());
                    printf ("declarationStatement2->get_firstNondefiningDeclaration() = %p \n",declarationStatement2->get_firstNondefiningDeclaration());
                  }

               printf ("Source code positions of ORD violation: \n");
               node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug");
               duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug");
             }
        }
#endif
  // ROSE_ASSERT(nodeString == duplicateNodeFromOriginalASTstring);
     ROSE_ASSERT(passesODR == true);

     return passesODR;
   }