apicompatanamdw/compatanalysercmd/headeranalyser/src/BBCAnalyser.cpp
changeset 0 638b9c697799
child 3 ebe3f8f03b59
equal deleted inserted replaced
-1:000000000000 0:638b9c697799
       
     1 /*
       
     2 * Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CmdGlobals.h"
       
    20 #ifdef __WIN__
       
    21 #pragma warning(disable:4786)
       
    22 #endif
       
    23 
       
    24 #include <assert.h>
       
    25 #include <map>
       
    26 #include <list>
       
    27 #include <string>
       
    28 #include <time.h>
       
    29 #include <xercesc/dom/DOM.hpp>
       
    30 
       
    31 #include "BBCAnalyser.h"
       
    32 #include "BBCPreAnalysis.h"
       
    33 #include "Issues.h"
       
    34 #include "ReportGenerator.h"
       
    35 #include "ReportIssue.h"
       
    36 #include "XMLUtils.h"
       
    37 #include "XMLStringConst.h"
       
    38 #include "VariableNodeAnalysis.h"
       
    39 #include "EnumNodeAnalysis.h"
       
    40 #include "FunctionNodeAnalysis.h"
       
    41 #include "TypedefNodeAnalysis.h"
       
    42 #include "OperatorFunctionNodeAnalysis.h"
       
    43 #include "UnionNodeAnalysis.h"
       
    44 #include "ClassNodeAnalysis.h"
       
    45 #include "StructNodeAnalysis.h"
       
    46 #include "NodeTypeComparator.h"
       
    47 #include "Utils.h"
       
    48 
       
    49 using namespace std;
       
    50 
       
    51 XERCES_CPP_NAMESPACE_USE
       
    52 
       
    53 
       
    54 
       
    55 struct ConstructorElement
       
    56 {
       
    57     const XMLCHAR* iEntityName;	
       
    58     NodeAnalysis::Constructor iConstructor;
       
    59 };
       
    60 
       
    61 // Table of different node analysis constructor functions
       
    62 const ConstructorElement KConstructorTable[KEntityComparisonTableCount]=
       
    63     {
       
    64     {KXMLBaseString,UnderConstructionNodeAnalysis::Construct},
       
    65     {KXMLFundamentalTypeString,UnderConstructionNodeAnalysis::Construct},
       
    66     {KXMLTypedefString,TypedefNodeAnalysis::Construct},//
       
    67     {KXMLNamespaceString,UnderConstructionNodeAnalysis::Construct},
       
    68     {KXMLCvQualifiedTypeString,UnderConstructionNodeAnalysis::Construct},
       
    69     {KXMLVariableString,VariableNodeAnalysis::Construct},//
       
    70     {KXMLFundamentalTypeString,UnderConstructionNodeAnalysis::Construct},
       
    71     {KXMLTypedefString,UnderConstructionNodeAnalysis::Construct},
       
    72     {KXMLNamespaceString,UnderConstructionNodeAnalysis::Construct},
       
    73     {KXMLFunctionString,FunctionNodeAnalysis::Construct},//
       
    74     {KXMLEnumerationString,EnumNodeAnalysis::Construct},//
       
    75     {KXMLFieldString,UnderConstructionNodeAnalysis::Construct},
       
    76     {KXMLArgumentString,UnderConstructionNodeAnalysis::Construct},
       
    77     {KXMLEllipsisString,UnderConstructionNodeAnalysis::Construct},
       
    78     {KXMLArrayTypeString,UnderConstructionNodeAnalysis::Construct},
       
    79     {KXMLClassString,ClassNodeAnalysis::Construct},//
       
    80     {KXMLConstructorString,UnderConstructionNodeAnalysis::Construct},
       
    81     {KXMLConverterString,UnderConstructionNodeAnalysis::Construct},
       
    82     {KXMLDestructorString,UnderConstructionNodeAnalysis::Construct},
       
    83     {KXMLEnumValueString,UnderConstructionNodeAnalysis::Construct},
       
    84     {KXMLFileString,UnderConstructionNodeAnalysis::Construct},
       
    85     {KXMLFunctionTypeString,UnderConstructionNodeAnalysis::Construct},
       
    86     {KXMLMethodString,UnderConstructionNodeAnalysis::Construct},
       
    87     {KXMLMethodTypeString,UnderConstructionNodeAnalysis::Construct},
       
    88     {KXMLNamespaceAliasString,UnderConstructionNodeAnalysis::Construct},
       
    89     {KXMLOffsetTypeString,UnderConstructionNodeAnalysis::Construct},
       
    90     {KXMLOperatorFunctionString,OperatorFunctionNodeAnalysis::Construct},
       
    91     {KXMLOperatorMethodString,UnderConstructionNodeAnalysis::Construct},
       
    92     {KXMLPointerTypeString,UnderConstructionNodeAnalysis::Construct},
       
    93     {KXMLReferenceTypeString,UnderConstructionNodeAnalysis::Construct},
       
    94     {KXMLStructString,StructNodeAnalysis::Construct},
       
    95     {KXMLUnimplementedString,UnderConstructionNodeAnalysis::Construct},
       
    96     {KXMLUnionString,UnionNodeAnalysis::Construct}
       
    97     };
       
    98 
       
    99 // ----------------------------------------------------------------------------
       
   100 // NodeAnalysis::FindNodeAnalysisConstructor
       
   101 // ----------------------------------------------------------------------------
       
   102 //
       
   103 NodeAnalysis::Constructor FindNodeAnalysisConstructor(const XMLCh* nodeName)
       
   104 {
       
   105     int i = 0;
       
   106 
       
   107     for (i = 0;i < KEntityComparisonTableCount; ++i)
       
   108     {
       
   109         if ( Equals(KConstructorTable[i].iEntityName,nodeName) )
       
   110         {
       
   111             return KConstructorTable[i].iConstructor;
       
   112         }
       
   113     }
       
   114     return NULL;
       
   115 }
       
   116 
       
   117 // ----------------------------------------------------------------------------
       
   118 // BBCPreAnalysis::preAnalyseClassForVirtuality
       
   119 // 
       
   120 // Analyse for virtuality
       
   121 // ----------------------------------------------------------------------------
       
   122 //
       
   123 bool BBCPreAnalysis::preAnalyseClassForVirtuality(HANodeIterator classNode)
       
   124 {
       
   125 	bool isvirtual = false;
       
   126 	bool hasvirtualbases = false;
       
   127 
       
   128     //Check to see if we have already inspected this class
       
   129     if ( classNode.GetAttribute(KXMLBBCVirtualString) )
       
   130     {
       
   131         return classNode.CheckForBooleanAttribute(KXMLBBCVirtualString);
       
   132     }
       
   133 
       
   134     if ( classNode->hasChildNodes() )
       
   135     {
       
   136         //Check for virtual bases first as it is quicker
       
   137         DOMNodeList * childs = classNode->getChildNodes();
       
   138         
       
   139         XMLSize_t childcount = childs->getLength();
       
   140         
       
   141         for (unsigned int i = 0; i < childcount; ++i)
       
   142         {
       
   143             DOMNode* child = childs->item(i);
       
   144             
       
   145             //Skip any other than Base node
       
   146             if ( !Equals(child->getNodeName(),KXMLBaseString) ) 
       
   147             {
       
   148                 continue;
       
   149             }
       
   150             
       
   151             HANodeIterator childclass(classNode);
       
   152             childclass.current = child;
       
   153 
       
   154             if ( childclass.CheckForBooleanAttribute(KXMLVirtualString) )
       
   155             {
       
   156                 classNode.SetAttribute(KXMLBBCVirtualInheritanceString,KXML1String);
       
   157                 hasvirtualbases = true;
       
   158             }
       
   159 				
       
   160             const XMLCh * classid = childclass.GetAttribute(KXMLTypeString);
       
   161     
       
   162             assert(classid != NULL);
       
   163 
       
   164             bool ret = childclass.FindNodeById(classid);
       
   165 
       
   166             assert(ret == true);
       
   167 
       
   168             if ( preAnalyseClassForVirtuality( childclass ) )
       
   169             {
       
   170                 //The class is virtual, mark it to the xml document and return
       
   171                 classNode.SetAttribute(KXMLBBCVirtualString, KXML1String);
       
   172                 isvirtual = true;
       
   173             }
       
   174             
       
   175             if ( childclass.CheckForBooleanAttribute(KXMLBBCVirtualInheritanceString) )
       
   176             {
       
   177                 classNode.SetAttribute(KXMLBBCVirtualInheritanceString,KXML1String);
       
   178                 hasvirtualbases = true;
       
   179             }
       
   180         }
       
   181         
       
   182     }
       
   183 
       
   184     //We have already detected that this is virtual class
       
   185     if ( isvirtual )
       
   186     {
       
   187         ClassGenerateVirtualTable(classNode);
       
   188         return true;
       
   189     }
       
   190 
       
   191     //Go through the methods of the class and check them for virtuality
       
   192     const XMLCh* attributeValue = classNode.GetAttribute(KXMLMembersString);
       
   193     
       
   194     if (attributeValue)
       
   195     {
       
   196         BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString(attributeValue);
       
   197         auto_ptr<BaseRefVectorOf< XMLCh > > memberids(memberids_ptr);
       
   198 
       
   199         for (unsigned int i = 0; i < memberids->size(); ++i)
       
   200         {
       
   201             const XMLCh * memberid = memberids->elementAt(i);
       
   202             
       
   203             HANodeIterator member(classNode);
       
   204             bool memberfound = member.FindNodeById(memberid);
       
   205 
       
   206             if ( memberfound )
       
   207             {
       
   208                 if ( member.CheckForBooleanAttribute(KXMLVirtualString) ||
       
   209                     member.CheckForBooleanAttribute(KXMLPureVirtualString))
       
   210                 {
       
   211                     //Generate primary virtual table for the class
       
   212                     ClassGenerateVirtualTable(classNode);
       
   213                     //The class is virtual, mark it to the xml document and return
       
   214                     classNode.SetAttribute(KXMLBBCVirtualString, KXML1String);
       
   215                     return true;
       
   216                 }
       
   217             }
       
   218             else
       
   219             {
       
   220                 //The tree is broken
       
   221                 assert(false);
       
   222             }
       
   223         }
       
   224         //memberids->cleanup();
       
   225         //delete memberids;
       
   226     }
       
   227     
       
   228     classNode.SetAttribute(KXMLBBCVirtualString, KXML0String);
       
   229     return false;
       
   230 }
       
   231 
       
   232 // ----------------------------------------------------------------------------
       
   233 // BBCAnalyser::preAnalyseClassForDerivability
       
   234 //
       
   235 // Check for derivability. The class is derivable iff:
       
   236 // 1. Has a public or protected explicitely declared exported constructor
       
   237 // 2. Has a public or protected inline constructor
       
   238 // In GCCXML:
       
   239 // 
       
   240 // Check methods of type "Constructor" 
       
   241 //
       
   242 // Constructor type / attribute:| artificial | explicit | inline | exported
       
   243 //--------------------------------------------------------------------------
       
   244 // implicite inline constructor |     x     |     x     |   x    |          
       
   245 // inline constructor           |           |    (x)    |   x    |          
       
   246 // exported constructor         |           |    (x)    |        |    x     
       
   247 // ----------------------------------------------------------------------------
       
   248 //
       
   249 void BBCPreAnalysis::preAnalyseClassForDerivability(HANodeIterator classNode)
       
   250 {
       
   251     //Go through the methods of the class and check them for constructor
       
   252     const XMLCh* attributeValue = classNode.GetAttribute(KXMLMembersString);
       
   253 
       
   254     //Default to public desctructor as it is same as no desctructor at all
       
   255     classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessPublicString);
       
   256 	
       
   257     if (attributeValue)
       
   258     {
       
   259         BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString (attributeValue);
       
   260         auto_ptr<BaseRefVectorOf< XMLCh > > memberids(memberids_ptr);
       
   261 
       
   262         for (unsigned int i = 0; i < memberids->size(); ++i)
       
   263         {
       
   264             const XMLCh * memberid = memberids->elementAt(i);
       
   265             
       
   266             HANodeIterator member(classNode);
       
   267             
       
   268             if ( member.FindNodeById(memberid) )
       
   269             {
       
   270                 //The member is constructor
       
   271                 if ( Equals(member->getNodeName(),KXMLConstructorString) )
       
   272                 {
       
   273                     //Check if the constructor is protected or public
       
   274                     const XMLCh* accessAttribute = member.GetAttribute(KXMLAccessString);
       
   275                     
       
   276                     if ( Equals(accessAttribute,KXMLProtectedString) || Equals(accessAttribute,KXMLPublicString) )
       
   277                     {
       
   278                         //If the constructor is artificial (compiler generated) we need to check for the explicit attribute 
       
   279                         // to recognize the proper constructor and not the helper constructor generated by the compiler
       
   280                         bool artificial = member.CheckForBooleanAttribute(KXMLArtificialString);
       
   281                         
       
   282                         bool explicit_val = member.CheckForBooleanAttribute(KXMLExplicitString);
       
   283                         
       
   284                         bool inline_val = member.CheckForBooleanAttribute(KXMLInlineString);
       
   285                     
       
   286                         const XMLCh* attributeAttribute = member.GetAttribute(KXMLAttributeString);                            
       
   287                         //Check for export or inline
       
   288                         if ( ( inline_val && explicit_val && artificial ) || //the constructor is compiler generated inline function
       
   289                              ( inline_val && !artificial ) ||  //the constructor is explicitely declared inline function
       
   290                              (attributeAttribute && Equals(attributeAttribute,KXMLExportedString))  //the constructor is explicitely declared exported function
       
   291                             )
       
   292                             {
       
   293                                 if ( Equals(accessAttribute,KXMLProtectedString) )
       
   294                                 {
       
   295                                     //Is derivable class. Mark the node as one.
       
   296                                     classNode.SetAttribute(KXMLBBCProtectedConstructorString,KXML1String);
       
   297                                 }
       
   298                                 
       
   299                                 if ( Equals(accessAttribute,KXMLPublicString) )
       
   300                                 {
       
   301                                     classNode.SetAttribute(KXMLBBCPublicConstructorString,KXML1String);
       
   302                                     //Class is instantiable,too!!!
       
   303                                 }
       
   304                             }
       
   305                     }
       
   306                 } else if ( Equals(member->getNodeName(),KXMLDestructorString) )
       
   307                 {
       
   308                     //Check if the destructor is private, protected or public and accessibility
       
   309                     // if the desctructor is not accessible it is marked as private 
       
   310                     const XMLCh* accessAttribute = member.GetAttribute(KXMLAccessString);
       
   311                     
       
   312                     bool inline_val = member.CheckForBooleanAttribute(KXMLInlineString);
       
   313                     bool virtual_val = member.CheckForBooleanAttribute(KXMLVirtualString) ||
       
   314                                         member.CheckForBooleanAttribute(KXMLPureVirtualString);
       
   315                     bool exported_val = false; 
       
   316                     const XMLCh* attributeAttribute = member.GetAttribute(KXMLAttributeString);                            
       
   317                              
       
   318                     if (attributeAttribute && Equals(attributeAttribute,KXMLExportedString) )
       
   319                     {
       
   320                         exported_val = true;
       
   321                     }
       
   322 
       
   323                     if ( !Equals(accessAttribute,KXMLPrivateString) && (inline_val || virtual_val || exported_val) )
       
   324                     {
       
   325 
       
   326                         if ( Equals(accessAttribute,KXMLPublicString) )
       
   327                         {
       
   328                             classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessPublicString);
       
   329 
       
   330                         } else if ( Equals(accessAttribute,KXMLProtectedString) )
       
   331                         {
       
   332                             classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessProtectedString);
       
   333                         } 
       
   334                     }
       
   335                     else
       
   336                     {
       
   337                         classNode.SetAttribute(KXMLBBCDestructorAccessString,KXMLBBCAccessPrivateString);
       
   338                     }
       
   339                 }
       
   340 
       
   341             }
       
   342             else
       
   343             {
       
   344                 //The tree is broken
       
   345                 assert(false);
       
   346             }
       
   347         }
       
   348         //delete memberids;
       
   349     }
       
   350 }
       
   351 
       
   352 
       
   353 // ----------------------------------------------------------------------------
       
   354 // BBCAnalyser::preAnalyseClassForInlineFunctions
       
   355 // 
       
   356 // ----------------------------------------------------------------------------
       
   357 //
       
   358 void BBCPreAnalysis::preAnalyseClassForInlineFunctions(HANodeIterator classNode)
       
   359 {
       
   360     //Go through the methods of the class and check them for virtuality
       
   361     const XMLCh* attributeValue = classNode.GetAttribute(KXMLMembersString);
       
   362 
       
   363     if (attributeValue)
       
   364     {
       
   365         BaseRefVectorOf< XMLCh > * memberids_ptr = XMLString::tokenizeString (attributeValue);
       
   366         auto_ptr<BaseRefVectorOf< XMLCh > > memberids(memberids_ptr);
       
   367         bool hasPublicInline = false;
       
   368         bool hasProtectedInline = false;
       
   369         
       
   370         for (unsigned int i = 0; i < memberids->size(); ++i)
       
   371         {
       
   372             const XMLCh * memberid = memberids->elementAt(i);
       
   373             
       
   374             HANodeIterator member(classNode);
       
   375             
       
   376             if ( member.FindNodeById(memberid) )
       
   377             {
       
   378                 //Check every inline function but do not take artificial (compiler generated) functions into account
       
   379                 if ( member.CheckForBooleanAttribute(KXMLInlineString) && !member.CheckForBooleanAttribute(KXMLArtificialString) )
       
   380                 {
       
   381 
       
   382                     //Check if the constructor is protected or public
       
   383                     const XMLCh* attributeValue = member.GetAttribute(KXMLAccessString);
       
   384                     
       
   385                     if ( Equals(attributeValue,KXMLProtectedString) )
       
   386                     {
       
   387                         //The class has protected inline function
       
   388                         hasProtectedInline = true;
       
   389                         classNode.SetAttribute(KXMLBBCProtectedInlineString,KXML1String);
       
   390                     }
       
   391                     
       
   392                     if ( Equals(attributeValue,KXMLPublicString) )
       
   393                     {
       
   394                         //The class has public inline function
       
   395                         hasPublicInline = true;
       
   396                         classNode.SetAttribute(KXMLBBCPublicInlineString,KXML1String);
       
   397                     }
       
   398                     
       
   399                     //It is enough if we have public inline, the class is fully exposed
       
   400                     if ( hasPublicInline )
       
   401                     {
       
   402                         return;
       
   403                     }
       
   404                 }
       
   405             }
       
   406             else
       
   407             {
       
   408                 //The tree is broken
       
   409                 assert(false);
       
   410             }
       
   411         }
       
   412         //memberids->cleanup();
       
   413         //delete memberids;
       
   414     }
       
   415     
       
   416 }
       
   417 
       
   418 
       
   419 // ----------------------------------------------------------------------------
       
   420 // BBCAnalyser::preAnalyseClass
       
   421 // 
       
   422 // ----------------------------------------------------------------------------
       
   423 //
       
   424 void BBCPreAnalysis::preAnalyseClass(HANodeIterator classNode)
       
   425 {
       
   426     preAnalyseClassForVirtuality(classNode);
       
   427     preAnalyseClassForDerivability(classNode);
       
   428     preAnalyseClassForInlineFunctions(classNode);
       
   429 }
       
   430 
       
   431 
       
   432 // ----------------------------------------------------------------------------
       
   433 // printNode
       
   434 // DEBUG method
       
   435 // 
       
   436 // ----------------------------------------------------------------------------
       
   437 //
       
   438 void printNode(HANodeIterator node)
       
   439 {
       
   440     DEBUG_STUFF(const XMLCh * name = node->getNodeName();)
       
   441     const XMLCh * value = node->getNodeValue();
       
   442  
       
   443     DEBUG_PRINT_XMLCh(name)
       
   444 
       
   445     if ( value )
       
   446     {
       
   447         DEBUG_PRINT(":")
       
   448         DEBUG_PRINT_XMLCh(value)
       
   449     }
       
   450 
       
   451     DOMNamedNodeMap * atts = node->getAttributes();
       
   452     if (atts)
       
   453     {
       
   454         DEBUG_PRINT(" attributes: ")
       
   455         XMLSize_t size = atts->getLength();
       
   456         for (unsigned int i = 0; i < size; ++i )
       
   457         {
       
   458             DOMNode * att = atts->item(i);
       
   459             HANodeIterator cit(node);
       
   460             cit.current = att;
       
   461             printNode(cit);
       
   462         }
       
   463     }
       
   464     DEBUG_PRINT("\n")
       
   465 }
       
   466 
       
   467 
       
   468 // ----------------------------------------------------------------------------
       
   469 // BBCAnalyser::preAnalyseGenerateMaps
       
   470 // 
       
   471 // ----------------------------------------------------------------------------
       
   472 //
       
   473 void BBCPreAnalysis::preAnalyseGenerateMaps(HANodeIterator rootnode, bool baseline)
       
   474 {
       
   475     //First generate the file maps	
       
   476     short nodetype = rootnode->getNodeType();
       
   477     assert(nodetype == DOMNode::ELEMENT_NODE);
       
   478 
       
   479 #ifndef NO_DBG
       
   480     DEBUG_PRINT("****************preAnalyse: Generating index*********************\n")
       
   481     DEBUG_STUFF(time_t starttime = time(NULL);)
       
   482 #endif
       
   483 
       
   484     DOMDocument * doc =  rootnode->getOwnerDocument();
       
   485     DOMNodeIterator * domit = doc->createNodeIterator (rootnode.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
       
   486     DOMNode * it = NULL;
       
   487     while ( NULL != (it = domit->nextNode()) )
       
   488     {
       
   489         HANodeIterator childit(rootnode);
       
   490         childit.current = it;
       
   491 
       
   492 #ifdef _DEBUG
       
   493         //printNode(childit);
       
   494         // Keep commented, too much stuff to print
       
   495 #endif
       
   496         if (DOMNode::ELEMENT_NODE == childit->getNodeType())
       
   497         {
       
   498             childit.IndexNode();
       
   499         }
       
   500     }
       
   501 #ifndef NO_DBG
       
   502     DEBUG_PRINT("****************preAnalyse: Generating index END*********************\n")
       
   503     DEBUG_STUFF(time_t endtime = time(NULL);)
       
   504     DEBUG_STUFF(time_t runningtime = endtime - starttime;)
       
   505     DEBUG_PRINT("ELAPSED TIME: ")
       
   506     DEBUG_PRINT((long)runningtime)
       
   507     DEBUG_PRINT("\n")
       
   508 
       
   509     DEBUG_PRINT("****************preAnalyse: Generating name map*********************\n")
       
   510     DEBUG_STUFF(time_t starttime2 = time(NULL);)
       
   511 #endif
       
   512 
       
   513     doc =  rootnode->getOwnerDocument();
       
   514     domit = doc->createNodeIterator (rootnode.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
       
   515     it = NULL;
       
   516     while ( NULL != (it = domit->nextNode()) )
       
   517     {
       
   518         HANodeIterator childit(rootnode);
       
   519         childit.current = it;		
       
   520 
       
   521         // Add node to name map if following conditions are true:
       
   522         // 1. Node is proper i.e. it is in proper context and it is not artificial (compiler generated).
       
   523         // 2. Node is named (class, enum, function.. etc.)
       
   524         // 3. It is declared in the analysed header OR it is not a baseline node. 
       
   525         //    Without this rule, classes that are moved to another, not to be analysed header,
       
   526         //    would not be properly analysed.
       
   527         if (IsProperNode(childit) && IsNamedNode(childit) && (childit.toBeAnalysed() || !baseline))
       
   528         {        
       
   529             const XMLCh* nodetype = childit->getNodeName();
       
   530             
       
   531             if ( Equals(nodetype,KXMLEnumerationString) )
       
   532             {
       
   533                 //Check to see if the enumeration is anonymous	
       
   534                 if ( IsAnonymous(childit) )
       
   535                 {
       
   536                     DOMNodeList* enumchilds = childit.GetElementsByTagName(KXMLEnumValueString);
       
   537                     XMLSize_t enumchildcount = enumchilds->getLength();
       
   538                     unsigned int i = 0;
       
   539                     for (i = 0; i < enumchildcount; ++i)
       
   540                     {
       
   541                         HANodeIterator enumchildit(childit);
       
   542                         enumchildit.current = enumchilds->item(i);
       
   543                         
       
   544                         enumchildit.NameNode(!baseline);
       
   545                         
       
   546                     }
       
   547 
       
   548                     continue;//Skip the enum naming 
       
   549                 }
       
   550             }
       
   551 
       
   552             childit.NameNode(!baseline);
       
   553         }
       
   554     }
       
   555 
       
   556 #ifndef NO_DBG
       
   557     DEBUG_PRINT("****************preAnalyse: Generating name map END*********************\n")
       
   558     DEBUG_STUFF(time_t endtime2 = time(NULL);)
       
   559     DEBUG_STUFF(time_t runningtime2 = endtime2 - starttime2;)
       
   560     DEBUG_PRINT("ELAPSED TIME: ")
       
   561     DEBUG_PRINT((long)runningtime2)
       
   562     DEBUG_PRINT("\n")
       
   563 #endif
       
   564 }
       
   565 
       
   566 
       
   567 // ----------------------------------------------------------------------------
       
   568 // BBCAnalyser::checkForEmptyFiles 
       
   569 // ----------------------------------------------------------------------------
       
   570 //
       
   571 vector<bool> BBCAnalyser::checkForEmptyFiles(HANodeIterator rootnode, const list<string>& filesToAnalyse, const list<string>& aMacroFiles)
       
   572 {
       
   573     DOMNodeList* childs = rootnode.GetElementsByTagName(KXMLFileString);
       
   574     XMLSize_t childcount = childs->getLength();
       
   575 
       
   576     vector<bool> filefound(filesToAnalyse.size(),false);
       
   577 
       
   578     for (unsigned int i = 0; i < childcount; ++i)
       
   579     {
       
   580         DOMNode* child = childs->item(i);
       
   581         HANodeIterator childit(rootnode);
       
   582         childit.current = child;        
       
   583         const XMLCh* filename = childit.GetAttribute(KXMLNameString);
       
   584         list<string>::const_iterator it = filesToAnalyse.begin();
       
   585         int j = 0;
       
   586         for (;it != filesToAnalyse.end(); ++it)
       
   587         {
       
   588             if ( CompareFileNames((*it),toString(filename)) )
       
   589             {
       
   590                 filefound[j] = true;
       
   591                 break;
       
   592             }
       
   593             ++j;
       
   594         }
       
   595     }
       
   596 	
       
   597 	//validate that file is not empty
       
   598 	//in case file only contained macros
       
   599 	if(!aMacroFiles.empty())
       
   600 	{
       
   601 		list<string>::const_iterator start = filesToAnalyse.begin();
       
   602 		for(unsigned int i=0; i < filesToAnalyse.size(); i++, start++)
       
   603 		{
       
   604 			if(!filefound[i])
       
   605 			{
       
   606 				list<string>::const_iterator mFiles = aMacroFiles.begin();
       
   607 				for(;mFiles != aMacroFiles.end();mFiles++)
       
   608 					if( toLowerCaseWin(*start) == *mFiles )
       
   609 					{
       
   610 						filefound[i] = true;
       
   611 						break;
       
   612 					}
       
   613 			}
       
   614 		}
       
   615 	}
       
   616 	return filefound;
       
   617 }
       
   618 
       
   619 
       
   620 // ----------------------------------------------------------------------------
       
   621 // BBCAnalyser::preAnalyse
       
   622 // 
       
   623 // ----------------------------------------------------------------------------
       
   624 //
       
   625 void BBCPreAnalysis::preAnalyse(HANodeIterator rootnode,const list<string> & filesToAnalyse, bool baseline)
       
   626 {
       
   627     short nodetype = rootnode->getNodeType();    
       
   628     assert(nodetype == DOMNode::ELEMENT_NODE);
       
   629 
       
   630     //First generate the file maps	
       
   631 #ifndef NO_DBG
       
   632     DEBUG_PRINT("****************preAnalyse: Generating file maps*********************\n")
       
   633     DEBUG_STUFF(time_t starttime = time(NULL);)
       
   634 #endif
       
   635 
       
   636     DOMNodeList* childs = rootnode.GetElementsByTagName(KXMLFileString);
       
   637     XMLSize_t childcount = childs->getLength();
       
   638 #ifndef NO_DBG
       
   639     DEBUG_PRINT("preAnalyseGenerateMaps: Files to analyse: ")
       
   640     DEBUG_PRINT(childcount)
       
   641     DEBUG_PRINT("\n")
       
   642 #endif
       
   643 
       
   644     unsigned int i = 0;
       
   645     for (i = 0; i < childcount; ++i)
       
   646     {
       
   647         DOMNode* child = childs->item(i);
       
   648         HANodeIterator childit(rootnode);
       
   649         childit.current = child;
       
   650         bool filetoanalyse = false;
       
   651         const XMLCh* filename = childit.GetAttribute(KXMLNameString);
       
   652         list<string>::const_iterator it = filesToAnalyse.begin();
       
   653         int i = 0;
       
   654         for (;it != filesToAnalyse.end(); ++it)
       
   655         {
       
   656             if ( CompareFileNames((*it),toString(filename)) )
       
   657             {
       
   658                 filetoanalyse = true;
       
   659                 break;
       
   660             }
       
   661             ++i;
       
   662         }
       
   663         childit.IndexFileNode(filetoanalyse);
       
   664     }
       
   665 #ifndef NO_DBG
       
   666     DEBUG_PRINT("****************preAnalyse: Generating file maps END*********************\n")
       
   667     DEBUG_STUFF(time_t endtime = time(NULL);)
       
   668     DEBUG_STUFF(time_t runningtime = endtime - starttime;)
       
   669     DEBUG_PRINT("ELAPSED TIME: ")
       
   670     DEBUG_PRINT((long)runningtime)
       
   671     DEBUG_PRINT("\n")
       
   672 #endif
       
   673 
       
   674     preAnalyseGenerateMaps(rootnode,baseline);
       
   675 
       
   676     //rootnode.iNodeIndex.DumpTables();
       
   677 
       
   678 #ifndef NO_DBG
       
   679     DEBUG_PRINT("****************preAnalyse: Preanalysing classes*********************\n")
       
   680     DEBUG_STUFF(time_t starttime2 = time(NULL);)
       
   681     DEBUG_PRINT("preAnalyse: Nodes to analyse: ")
       
   682     DEBUG_PRINT(childcount)
       
   683     DEBUG_PRINT("\n")
       
   684 #endif
       
   685 
       
   686     DOMDocument * doc =  rootnode->getOwnerDocument();
       
   687     DOMNodeIterator * domit = doc->createNodeIterator (rootnode.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
       
   688     DOMNode * it = NULL;
       
   689     while ( NULL != (it = domit->nextNode()) )
       
   690     {
       
   691         HANodeIterator childit(rootnode);
       
   692         childit.current = it;
       
   693 #ifdef _DEBUG
       
   694         // printNode(childit);
       
   695         // Keep commented, too much stuff to print
       
   696 #endif      
       
   697         const XMLCh * nodename = childit->getNodeName();
       
   698         if ( DOMNode::ELEMENT_NODE == childit->getNodeType() && childit.toBeAnalysed() && 
       
   699              ( Equals(nodename,KXMLClassString) || Equals(nodename,KXMLStructString)
       
   700 			 || Equals(nodename,KXMLUnionString))
       
   701            )
       
   702         {
       
   703             preAnalyseClass(childit);
       
   704         }
       
   705     }
       
   706     
       
   707 #ifndef NO_DBG
       
   708     DEBUG_PRINT("****************preAnalyse: Preanalysing classes END*********************\n")
       
   709     DEBUG_STUFF(time_t endtime2 = time(NULL);)
       
   710     DEBUG_STUFF(time_t runningtime2 = endtime2 - starttime2;)
       
   711     DEBUG_PRINT("ELAPSED TIME: ")
       
   712     DEBUG_PRINT((long)runningtime2)
       
   713     DEBUG_PRINT("\n")
       
   714 #endif
       
   715 }
       
   716 
       
   717 // ----------------------------------------------------------------------------
       
   718 // BBCAnalyser::nodeAnalyseTrees
       
   719 // ----------------------------------------------------------------------------
       
   720 //
       
   721 int BBCAnalyser::nodeAnalyseTrees(HANodeIterator baseline, HANodeIterator current,const list< pair<string,string> >& filesToAnalyse)
       
   722 {
       
   723     //Find out the files to be processed
       
   724     short nodetype = baseline->getNodeType();    
       
   725     assert(nodetype == DOMNode::ELEMENT_NODE);
       
   726     nodetype = current->getNodeType();    
       
   727     assert(nodetype == DOMNode::ELEMENT_NODE);
       
   728 
       
   729     int ret = 0;
       
   730 
       
   731     DOMDocument * doc =  baseline->getOwnerDocument();
       
   732     DOMNodeIterator * domit = doc->createNodeIterator (baseline.current,DOMNodeFilter::SHOW_ELEMENT, NULL, true);
       
   733     DOMNode * it = NULL;
       
   734 
       
   735     while ( NULL != (it = domit->nextNode()) )
       
   736     {
       
   737         HANodeIterator childit(baseline);
       
   738         childit.current = it;
       
   739 
       
   740          if (IsNamedNode(childit) && IsProperNode(childit) && childit.toBeAnalysed())
       
   741         {
       
   742             if ( !CheckAccessibility(childit) )
       
   743             {
       
   744                 //The node is not visible, so no need to analyse
       
   745                 continue;
       
   746             }
       
   747             HANodeIterator currentit(current);
       
   748 			
       
   749             const XMLCh* name = childit.GetAttribute(KXMLNameString);
       
   750             if ( StartsWith(name,KXMLInternalNamePrefix) )
       
   751             {
       
   752                 //Skip compiler generated pseudo elements
       
   753                 continue;
       
   754             }
       
   755             
       
   756             const XMLCh* id = childit.GetAttribute(KXMLIdString);
       
   757             DEBUG_PRINT("Analysing:")
       
   758             if ( name )
       
   759             {
       
   760                 DEBUG_PRINT_XMLCh(name)
       
   761             }
       
   762             if ( id )
       
   763             {
       
   764                 DEBUG_PRINT(":")
       
   765                 DEBUG_PRINT_XMLCh(id)
       
   766             }
       
   767             DEBUG_PRINT("\n")
       
   768 
       
   769 
       
   770             NodeAnalysis::Constructor constructorfunction = FindNodeAnalysisConstructor(childit->getNodeName());
       
   771             NodeAnalysis * analyser = constructorfunction();
       
   772         
       
   773             ret += analyser->FindNodeAndAnalyse(childit,currentit);
       
   774             delete analyser;			
       
   775         }
       
   776     }
       
   777 
       
   778     return ret;
       
   779 }
       
   780 
       
   781 // ----------------------------------------------------------------------------
       
   782 // BBCAnalyser::analyseTrees
       
   783 // ----------------------------------------------------------------------------
       
   784 //
       
   785 int BBCAnalyser::analyseTrees(DOMNode* baseline, DOMNode* current,const list< pair<string,string> >& filesToAnalyse, const list<string>& aMacroFiles)
       
   786 {
       
   787 #ifndef NO_DBG
       
   788     DEBUG_PRINT("****************Analyse: ANALYSE starts*********************\n")
       
   789     DEBUG_STUFF(time_t starttime = time(NULL);)
       
   790 #endif
       
   791 
       
   792     iBaselineIndex.clear();
       
   793     iCurrentIndex.clear();
       
   794     
       
   795     HANodeIterator baselineit(baseline,iBaselineIndex,iReport, filesToAnalyse, true );
       
   796     HANodeIterator currentit(current,iCurrentIndex,iReport, filesToAnalyse, false);
       
   797     
       
   798     list<string> basefiles, currentfiles;
       
   799     list< pair<string,string> >::const_iterator it = filesToAnalyse.begin();
       
   800     
       
   801     for (; it != filesToAnalyse.end(); ++it)
       
   802     {
       
   803         basefiles.push_back((*it).first);
       
   804         currentfiles.push_back((*it).second);
       
   805     }
       
   806 
       
   807     preAnalysis.preAnalyse(baselineit,basefiles,true);
       
   808     preAnalysis.preAnalyse(currentit,currentfiles,false);
       
   809 
       
   810     vector<bool> bfilefound;
       
   811     bfilefound = checkForEmptyFiles(baselineit,basefiles,aMacroFiles);
       
   812     
       
   813     vector<bool> cfilefound;
       
   814     cfilefound = checkForEmptyFiles(currentit,currentfiles,aMacroFiles);
       
   815 
       
   816     list<pair<string,string> >::const_iterator fileit = filesToAnalyse.begin();
       
   817     size_t i = 0;
       
   818 
       
   819     for (i=0;i < bfilefound.size(); ++i,++fileit)
       
   820     {
       
   821         if ( !cfilefound[i] && !bfilefound[i] )
       
   822         {
       
   823             // Serious problem, the analysed file is not in the GCCXML output
       
   824             iReport.addIssue(fileit->first,"", EIssueIdentityFile, EIssueTypeEmpty, 
       
   825             BCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), SCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), "", 0, fileit->second, "");
       
   826         }
       
   827         else if ( !bfilefound[i] )
       
   828         {
       
   829             // Serious problem, the analysed file is not in the GCCXML output
       
   830             iReport.addIssue(fileit->first,"", EIssueIdentityFile, EIssueTypeEmpty, 
       
   831             BCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), SCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), "", 0, fileit->second, "");
       
   832         }
       
   833         else if ( !cfilefound[i])
       
   834         {
       
   835             // Serious problem, the analysed file is not in the GCCXML output
       
   836             iReport.addIssue(fileit->first,"", EIssueIdentityFile, EIssueTypeEmpty, 
       
   837 				    BCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), SCseverityAccessible<EIssueIdentityFile,EIssueTypeEmpty>(true), "", 0, fileit->second, "",false);
       
   838         }
       
   839     }
       
   840 
       
   841     //baselineit.iNodeIndex.DumpTables();
       
   842     //currentit.iNodeIndex.DumpTables();
       
   843 
       
   844 #ifndef NO_DBG
       
   845     DEBUG_PRINT("****************nodeAnalyse: Analysing*********************\n")
       
   846     DEBUG_STUFF(time_t starttime2 = time(NULL);)
       
   847 #endif
       
   848 
       
   849     int ret = nodeAnalyseTrees(baselineit, currentit, filesToAnalyse);
       
   850 #ifndef NO_DBG
       
   851     DEBUG_STUFF(time_t endtime2 = time(NULL);)
       
   852     DEBUG_STUFF(time_t runningtime2 = endtime2- starttime2;)
       
   853     DEBUG_PRINT("****************nodeAnalyse: Analysing END*********************\n")
       
   854     DEBUG_PRINT("ELAPSED TIME: ")
       
   855     DEBUG_PRINT((long)runningtime2)
       
   856     DEBUG_PRINT("\n")
       
   857 
       
   858     DEBUG_PRINT("****************Analyse: ANALYSE END*********************\n")
       
   859     DEBUG_STUFF(time_t endtime = time(NULL);)
       
   860     DEBUG_STUFF(time_t runningtime = endtime - starttime;)
       
   861     DEBUG_PRINT("ELAPSED TIME: ")
       
   862     DEBUG_PRINT((long)runningtime)
       
   863     DEBUG_PRINT("\n")
       
   864 #endif
       
   865 
       
   866     return ret;
       
   867 }
       
   868 
       
   869 
       
   870 // ----------------------------------------------------------------------------
       
   871 // BBCAnalyser::BBCAnalyser
       
   872 // ----------------------------------------------------------------------------
       
   873 //
       
   874 BBCAnalyser::BBCAnalyser(ReportGenerator & report):
       
   875 iReport(report)
       
   876 {
       
   877 }
       
   878 
       
   879 
       
   880 // ----------------------------------------------------------------------------
       
   881 // NodeAnalysis::findNode
       
   882 // 
       
   883 // ----------------------------------------------------------------------------
       
   884 //
       
   885 DOMNode* NodeAnalysis::findNode(HANodeIterator nodetofind, HANodeIterator findfrom )
       
   886 {
       
   887     DOMNode * ret = NULL;
       
   888 
       
   889     pair<const XMLCh*,const XMLCh*> fqname = nodetofind.GetFullyQualifiedName();
       
   890 #ifndef NO_DBG
       
   891     DEBUG_PRINT("Finding node from current three with fqname: ")
       
   892     DEBUG_PRINT_XMLCh(fqname.first)
       
   893     DEBUG_PRINT(" ... ")
       
   894 #endif
       
   895 
       
   896     if ( findfrom.FindNodeByName(fqname) )
       
   897     {
       
   898         ret = findfrom.current;
       
   899     }
       
   900     return ret;
       
   901 }
       
   902 
       
   903 ///////////////////////////////UnderConstructionNodeAnalysis////////////////////////////
       
   904 
       
   905 // ----------------------------------------------------------------------------
       
   906 // UnderConstructionNodeAnalysis::Construct
       
   907 // 
       
   908 // ----------------------------------------------------------------------------
       
   909 //
       
   910 NodeAnalysis* UnderConstructionNodeAnalysis::Construct()
       
   911 {
       
   912     return new UnderConstructionNodeAnalysis();
       
   913 }
       
   914 
       
   915 
       
   916 // ----------------------------------------------------------------------------
       
   917 // UnderConstructionNodeAnalysis::Analyse
       
   918 // 
       
   919 // ----------------------------------------------------------------------------
       
   920 //
       
   921 int UnderConstructionNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
       
   922 {
       
   923     assert(
       
   924         Equals(baseline->getNodeName(), current->getNodeName())
       
   925         );
       
   926 
       
   927     if (report)
       
   928     {
       
   929         AddIssue<EIssueIdentityFile, EIssueTypeUnderConstruction>(&baseline, baseline,0);
       
   930     }
       
   931     return 1;
       
   932 }
       
   933 
       
   934 
       
   935 // ----------------------------------------------------------------------------
       
   936 // UnderConstructionNodeAnalysis::FindNodeAndAnalyse
       
   937 // 
       
   938 // ----------------------------------------------------------------------------
       
   939 //
       
   940 int UnderConstructionNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
   941 {
       
   942     AddIssue<EIssueIdentityFile,EIssueTypeUnderConstruction>(&baseline,baseline,0);
       
   943     return 1;
       
   944 }
       
   945 ////////////////////////////////////////////////////////////////////////////////////////
       
   946 ///////////////////////////////VariableNodeAnalysis/////////////////////////////////////
       
   947 
       
   948 
       
   949 // ----------------------------------------------------------------------------
       
   950 // VariableNodeAnalysis::Construct
       
   951 // ----------------------------------------------------------------------------
       
   952 //
       
   953 NodeAnalysis* VariableNodeAnalysis::Construct()
       
   954 {
       
   955     return new VariableNodeAnalysis();
       
   956 }
       
   957 
       
   958 // ----------------------------------------------------------------------------
       
   959 // VariableNodeAnalysis::FindNodeAndAnalyse 
       
   960 // ----------------------------------------------------------------------------
       
   961 //
       
   962 int VariableNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
   963 {
       
   964     DOMNode* node = NodeAnalysis::findNode(baseline,current);
       
   965     if ( !node )
       
   966     {
       
   967         AddIssue<EIssueIdentityVariable, EIssueTypeRemoval>(&baseline, baseline,0);
       
   968         return 1;
       
   969     }
       
   970     current.current = node;
       
   971 
       
   972     return this->Analyse(baseline,current);
       
   973 }
       
   974 
       
   975 
       
   976 // ----------------------------------------------------------------------------
       
   977 // VariableNodeAnalysis::Analyse
       
   978 // ----------------------------------------------------------------------------
       
   979 //
       
   980 int VariableNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
       
   981 {
       
   982     assert( Equals(KXMLVariableString, baseline->getNodeName()) &&
       
   983         Equals(KXMLVariableString, current->getNodeName()) &&
       
   984         Equals(baseline->getNodeName(), current->getNodeName())
       
   985         );
       
   986 
       
   987     int ret = 0;
       
   988 
       
   989 	int lineNo = 0;
       
   990 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
   991 	lineNo = atoi(toString(lineNumber).c_str());
       
   992 
       
   993     if ( IsAnonymousType(baseline) )
       
   994     {
       
   995         //We need to to comparison between the baseline type and current type anonymously
       
   996     
       
   997         HANodeIterator baselinetypeit(baseline);
       
   998         HANodeIterator currenttypeit(current);
       
   999 
       
  1000         const XMLCh* baselinetypeid = baseline.GetAttribute(KXMLTypeString);
       
  1001         const XMLCh* currenttypeid = current.GetAttribute(KXMLTypeString);
       
  1002 
       
  1003         assert( baselinetypeid && currenttypeid);
       
  1004 
       
  1005         bool ret1 = baselinetypeit.FindNodeById(baselinetypeid);
       
  1006         bool ret2 = currenttypeit.FindNodeById(currenttypeid);
       
  1007 
       
  1008         assert(ret1 && ret2);
       
  1009 
       
  1010         HANodeIterator baselinetypeanonit(baselinetypeit);
       
  1011         HANodeIterator currenttypeanonit(currenttypeit);
       
  1012         ret1 = FindAnonymousType(baselinetypeit,baselinetypeanonit);
       
  1013         ret2 = FindAnonymousType(currenttypeit,currenttypeanonit);
       
  1014         
       
  1015         assert(ret1);
       
  1016 
       
  1017         if ( !ret2 || !baselinetypeanonit.IsSameNodeType(currenttypeanonit) )
       
  1018         {
       
  1019             if (report)
       
  1020             {
       
  1021                 AddIssue<EIssueIdentityVariable, EIssueTypeChangeInType>(&baseline, current,lineNo);
       
  1022             }
       
  1023             ++ret;
       
  1024         }
       
  1025         else
       
  1026         {
       
  1027 
       
  1028             NodeAnalysis::Constructor constructorfunction = FindNodeAnalysisConstructor(baselinetypeanonit->getNodeName());
       
  1029             NodeAnalysis * analyser = constructorfunction();
       
  1030             int ret = analyser->Analyse(baselinetypeanonit,currenttypeanonit,false);
       
  1031             if ( ret > 0 )
       
  1032             {
       
  1033                 if (report)
       
  1034                 {
       
  1035                     AddIssue<EIssueIdentityVariable, EIssueTypeChangeInType>(&baseline, current,lineNo);
       
  1036                 }
       
  1037                 ++ret;
       
  1038             }
       
  1039             delete analyser;
       
  1040         }
       
  1041     }
       
  1042     else
       
  1043     {
       
  1044         //{KXMLTypeString,EIdAttribute}
       
  1045         if ( !CompareAttributes(baseline,current,KXMLTypeString,ETypeAttribute) )
       
  1046         {
       
  1047             if (report)
       
  1048             {
       
  1049                 AddIssue<EIssueIdentityVariable, EIssueTypeChangeInType>(&baseline, current,lineNo);
       
  1050             }
       
  1051             ++ret;
       
  1052         }
       
  1053     }
       
  1054 
       
  1055     //{KXMLInitString,EOptionalSimpleAttribute}
       
  1056     if ( !CompareAttributes(baseline,current,KXMLInitString,EOptionalSimpleAttribute) )
       
  1057     {
       
  1058         if (report)
       
  1059         {
       
  1060             AddIssue<EIssueIdentityVariable, EIssueTypeChangeInInitialisation>(&baseline, current,lineNo);
       
  1061         }
       
  1062         ++ret;
       
  1063     }
       
  1064 
       
  1065 	if (!CheckAccessModifier(baseline,current))
       
  1066     {
       
  1067         if (report)
       
  1068         {
       
  1069             //AddIssue<iIdentity,EIssueTypeAccess>(&baseline, current);
       
  1070 			AddIssue<EIssueIdentityVariable,EIssueTypeAccess>(&baseline, current,lineNo);
       
  1071         }
       
  1072         ret += 1;
       
  1073     }
       
  1074     
       
  1075     return ret;
       
  1076 }
       
  1077 
       
  1078 ////////////////////////////////////////////////////////////////////////////////////////
       
  1079 ///////////////////////////////EnumNodeAnalysis/////////////////////////////////////////
       
  1080 
       
  1081 // ----------------------------------------------------------------------------
       
  1082 // EnumNodeAnalysis::Construct
       
  1083 // 
       
  1084 // ----------------------------------------------------------------------------
       
  1085 //
       
  1086 NodeAnalysis* EnumNodeAnalysis::Construct()
       
  1087 {
       
  1088     return new EnumNodeAnalysis;
       
  1089 }
       
  1090 
       
  1091 // ----------------------------------------------------------------------------
       
  1092 // EnumNodeAnalysis::FindNodeAndAnalyse
       
  1093 // 
       
  1094 // ----------------------------------------------------------------------------
       
  1095 //
       
  1096 int EnumNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
  1097 {
       
  1098     int ret = 0;
       
  1099     if ( IsAnonymous(baseline) )
       
  1100     {
       
  1101         DOMNodeList* enumchilds = baseline.GetElementsByTagName(KXMLEnumValueString);
       
  1102         XMLSize_t enumchildcount = enumchilds->getLength();
       
  1103         unsigned int i = 0;
       
  1104         for (i = 0; i < enumchildcount; ++i)
       
  1105         {
       
  1106 			int lineNo = 0;
       
  1107             HANodeIterator enumchildit(baseline);
       
  1108             enumchildit.current = enumchilds->item(i);
       
  1109             
       
  1110             DOMNode* node = NodeAnalysis::findNode(enumchildit,current);
       
  1111             if ( !node )
       
  1112             {
       
  1113                 AddIssue<EIssueIdentityEnumerationValue,EIssueTypeRemoval>(&enumchildit, enumchildit, 0, baseline.GetAttribute(KXMLFileIdString));
       
  1114                 ++ret;
       
  1115                 continue;
       
  1116             }
       
  1117             current.current = node;
       
  1118 			DOMNode* parentnode = node->getParentNode();
       
  1119 			const XMLCh* lineNumber = GetAttribute(parentnode,KXMLLineString);
       
  1120 			lineNo = atoi(toString(lineNumber).c_str());
       
  1121 
       
  1122             if ( !CheckEnumValue(enumchildit,current) )
       
  1123             {
       
  1124                 AddIssue<EIssueIdentityEnumerationValue,EIssueTypeChangeInInitialisation>(&enumchildit, current, lineNo, baseline.GetAttribute(KXMLFileIdString));
       
  1125                 ++ret;
       
  1126             }
       
  1127 			HANodeIterator currentparent(current);
       
  1128 			if ( FindParentContext(current, currentparent))
       
  1129 			{
       
  1130 				if ( !CheckAccessModifier(baseline,currentparent) )
       
  1131 				{
       
  1132 					AddIssue<EIssueIdentityEnumerationValue,EIssueTypeAccess>(&enumchildit, current, lineNo, baseline.GetAttribute(KXMLFileIdString));
       
  1133 					++ret;
       
  1134 				}
       
  1135 			}
       
  1136         }
       
  1137     }
       
  1138     else
       
  1139     {
       
  1140 
       
  1141          DOMNode* node = NodeAnalysis::findNode(baseline,current);
       
  1142         if ( !node )
       
  1143         {
       
  1144             AddIssue<EIssueIdentityEnumeration,EIssueTypeRemoval>(&baseline, baseline,0);
       
  1145             return 1;
       
  1146         }
       
  1147         current.current = node;
       
  1148 
       
  1149         ret += this->Analyse(baseline,current);
       
  1150     }
       
  1151     return ret;
       
  1152 }
       
  1153 
       
  1154 
       
  1155 // ----------------------------------------------------------------------------
       
  1156 // EnumNodeAnalysis::CheckEnumValue
       
  1157 // 
       
  1158 // ----------------------------------------------------------------------------
       
  1159 //
       
  1160 bool EnumNodeAnalysis::CheckEnumValue(HANodeIterator baseline,HANodeIterator current)
       
  1161 {
       
  1162 
       
  1163     return CompareNodes(baseline,current);
       
  1164 }
       
  1165 
       
  1166 // ----------------------------------------------------------------------------
       
  1167 // EnumNodeAnalysis::Analyse
       
  1168 // 
       
  1169 // ----------------------------------------------------------------------------
       
  1170 //
       
  1171 int EnumNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
       
  1172 {
       
  1173     assert( Equals(KXMLEnumerationString, baseline->getNodeName()) &&
       
  1174             Equals(KXMLEnumerationString, current->getNodeName()) &&
       
  1175             Equals(baseline->getNodeName(), current->getNodeName())
       
  1176             );
       
  1177 
       
  1178 
       
  1179     int ret = 0;
       
  1180 	int lineNo = 0;
       
  1181 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  1182 	lineNo = atoi(toString(lineNumber).c_str());
       
  1183 
       
  1184     //{KXMLAlignString,ESimpleAttribute}
       
  1185     if ( !CompareAttributes(baseline,current,KXMLAlignString,ESimpleAttribute) )
       
  1186     {
       
  1187         if (report)
       
  1188         {
       
  1189             AddIssue<EIssueIdentityEnumeration,EIssueTypeAlign>(&baseline, current,lineNo);
       
  1190         }
       
  1191         ++ret;
       
  1192     }
       
  1193 
       
  1194     //{KXMLSizeString,ESimpleAttribute}
       
  1195     if ( !CompareAttributes(baseline,current,KXMLSizeString,ESimpleAttribute) )
       
  1196     {
       
  1197         if (report)
       
  1198         {
       
  1199             AddIssue<EIssueIdentityEnumeration,EIssueTypeSize>(&baseline, current,lineNo);
       
  1200         }
       
  1201         ++ret;
       
  1202     }
       
  1203 
       
  1204 	if (!CheckAccessModifier(baseline,current))
       
  1205     {
       
  1206         if (report)
       
  1207         {
       
  1208             //AddIssue<iIdentity,EIssueTypeAccess>(&baseline, current);
       
  1209 			AddIssue<EIssueIdentityEnumeration, EIssueTypeAccess>(&baseline, current,lineNo);
       
  1210         }
       
  1211         ++ret;
       
  1212     }
       
  1213 
       
  1214     //Check the enum values
       
  1215     DOMNodeList* baselinechilds = baseline.GetElementsByTagName(KXMLEnumValueString);
       
  1216     DOMNodeList* currentchilds = current.GetElementsByTagName(KXMLEnumValueString);
       
  1217    
       
  1218     XMLSize_t baselinechildcount = baselinechilds->getLength();
       
  1219     XMLSize_t currentchildcount = currentchilds->getLength();
       
  1220 
       
  1221     unsigned int i = 0;
       
  1222     for (i = 0; i < baselinechildcount; ++i)
       
  1223     {
       
  1224         HANodeIterator baselineit(baseline);
       
  1225         baselineit.current = baselinechilds->item(i);
       
  1226         unsigned int ii = 0;
       
  1227         for (ii = 0; ii < currentchildcount; ++ii)
       
  1228         {
       
  1229             HANodeIterator currentit(current);
       
  1230             currentit.current = currentchilds->item(ii);
       
  1231 
       
  1232             if ( CompareAttributes(baselineit,currentit,KXMLNameString,ESimpleAttribute)  )
       
  1233             {
       
  1234                 if ( !CompareAttributes(baselineit,currentit,KXMLInitString,ESimpleAttribute) )
       
  1235                 {
       
  1236                     if (report)
       
  1237                     {
       
  1238                         AddIssue<EIssueIdentityEnumeration,EIssueTypeChange>(&baseline, current,lineNo);
       
  1239                     }
       
  1240                     ++ret;
       
  1241                     return ret;
       
  1242                 }
       
  1243                 break;
       
  1244             }
       
  1245 
       
  1246         }
       
  1247 
       
  1248         if ( currentchildcount == ii )
       
  1249         {
       
  1250 
       
  1251             if (report)
       
  1252             {
       
  1253 				AddIssue<EIssueIdentityEnumerationValue,EIssueTypeRemoval>(&baseline, current,lineNo);
       
  1254             }
       
  1255             ++ret;
       
  1256             return ret;
       
  1257         }
       
  1258     }
       
  1259 
       
  1260     return ret;
       
  1261 }
       
  1262 
       
  1263 ////////////////////////////////////////////////////////////////////////////////////////
       
  1264 ///////////////////////////////FunctionNodeAnalysis/////////////////////////////////////
       
  1265 
       
  1266 
       
  1267 // ----------------------------------------------------------------------------
       
  1268 // FunctionNodeAnalysis::FunctionNodeAnalysis
       
  1269 // 
       
  1270 // ----------------------------------------------------------------------------
       
  1271 //
       
  1272 FunctionNodeAnalysis::FunctionNodeAnalysis():
       
  1273 iFuncType(EIssueIdentityExportedFunction)
       
  1274 {
       
  1275 }
       
  1276 
       
  1277 // ----------------------------------------------------------------------------
       
  1278 // FunctionNodeAnalysis::Construct
       
  1279 // 
       
  1280 // ----------------------------------------------------------------------------
       
  1281 //
       
  1282 NodeAnalysis* FunctionNodeAnalysis::Construct()
       
  1283 {
       
  1284     return new FunctionNodeAnalysis;
       
  1285 }
       
  1286 
       
  1287 // ----------------------------------------------------------------------------
       
  1288 // FunctionNodeAnalysis::FindNodeAndAnalyse
       
  1289 // 
       
  1290 // ----------------------------------------------------------------------------
       
  1291 //
       
  1292 int FunctionNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
  1293 {
       
  1294     if ( baseline.CheckForBooleanAttribute(KXMLInlineString) )
       
  1295     {
       
  1296         iFuncType = EIssueIdentityInlineFunction;
       
  1297     }
       
  1298 
       
  1299     //Check first if the function is exported
       
  1300     const XMLCh* attributeValue = baseline.GetAttribute(KXMLAttributeString);                            
       
  1301 
       
  1302     if ( (iFuncType == EIssueIdentityInlineFunction) || (attributeValue && Equals(attributeValue,KXMLExportedString)) )
       
  1303     {
       
  1304         DOMNode* node = NodeAnalysis::findNode(baseline,current);
       
  1305         if ( !node )
       
  1306         {
       
  1307 			//AddIssue<iFuncType,EIssueTypeRemoval>(&baseline, baseline);
       
  1308             AddIssueFunction<EIssueTypeRemoval>(&baseline,iFuncType,baseline,0);
       
  1309             return 1;
       
  1310         }
       
  1311         current.current = node;
       
  1312 
       
  1313         return this->Analyse(baseline,current);
       
  1314     }
       
  1315     
       
  1316     return 0;
       
  1317 }
       
  1318 
       
  1319 // ----------------------------------------------------------------------------
       
  1320 // FunctionNodeAnalysis::Analyse
       
  1321 // 
       
  1322 // ----------------------------------------------------------------------------
       
  1323 //
       
  1324 int FunctionNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
       
  1325 {
       
  1326     assert( 
       
  1327     Equals(baseline->getNodeName(), current->getNodeName())
       
  1328     );
       
  1329 
       
  1330     int ret = 0;
       
  1331 //<!ELEMENT FunctionType (Argument | Ellipsis)*>
       
  1332 //<!ATTLIST FunctionType attributes CDATA #IMPLIED>
       
  1333 //<!ATTLIST FunctionType id ID #REQUIRED>
       
  1334 //<!ATTLIST FunctionType returns IDREF #REQUIRED>
       
  1335 
       
  1336 	int lineNo = 0;
       
  1337 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  1338 	lineNo = atoi(toString(lineNumber).c_str());
       
  1339 
       
  1340     const XMLCh* attributeValue = current.GetAttribute(KXMLAttributeString);                            
       
  1341     if (
       
  1342         (
       
  1343             (iFuncType == EIssueIdentityInlineFunction) && !current.CheckForBooleanAttribute(KXMLInlineString) 
       
  1344         ) ||
       
  1345         ( 
       
  1346             (iFuncType == EIssueIdentityExportedFunction) && (!attributeValue || !Equals(attributeValue,KXMLExportedString) )
       
  1347             &&
       
  1348             (!current.CheckForBooleanAttribute(KXMLVirtualString))
       
  1349         )
       
  1350        )
       
  1351     {
       
  1352         if (report)
       
  1353         {
       
  1354 			AddIssueFunction<EIssueTypeRemoval>(&baseline,iFuncType,baseline,0);
       
  1355 
       
  1356         }
       
  1357         ++ret;
       
  1358         return ret;
       
  1359     }
       
  1360     
       
  1361     string basefuncsig = GenerateFunctionSignature(baseline);
       
  1362     string currentfuncsig = GenerateFunctionSignature(current);
       
  1363 
       
  1364     if ( basefuncsig != currentfuncsig )
       
  1365     {
       
  1366         ++ret;
       
  1367         if (report)
       
  1368         {
       
  1369 			AddIssueFunction<EIssueTypeParam>(&baseline,iFuncType,current,lineNo);
       
  1370         }
       
  1371     }
       
  1372     else
       
  1373     {
       
  1374         //Check also the default parameter values
       
  1375         DOMElement * baselineelement = static_cast<DOMElement*>(baseline.current);
       
  1376         DOMNodeList* baselinechilds = baselineelement->getChildNodes();
       
  1377         DOMElement * currentelement = static_cast<DOMElement*>(current.current);
       
  1378         DOMNodeList* currentchilds = currentelement->getChildNodes();
       
  1379         
       
  1380         XMLSize_t childcount = baselinechilds->getLength();
       
  1381 
       
  1382         unsigned int i = 0;
       
  1383         for (i = 0; i < childcount; ++i)
       
  1384         {
       
  1385             DOMNode* baselinechild = baselinechilds->item(i);
       
  1386             HANodeIterator baselinechildit(baseline);
       
  1387             baselinechildit.current = baselinechild;
       
  1388 
       
  1389             DOMNode* currentchild = currentchilds->item(i);
       
  1390             HANodeIterator currentchildit(current);
       
  1391             currentchildit.current = currentchild;
       
  1392 
       
  1393             short nodetype = baselinechildit->getNodeType();
       
  1394             if (nodetype == DOMNode::ELEMENT_NODE)
       
  1395             {
       
  1396 				const XMLCh * baselinesize = FindAttributeValueForType(baselinechildit,KXMLSizeString);
       
  1397 				const XMLCh * currentsize = FindAttributeValueForType(currentchildit,KXMLSizeString);
       
  1398 
       
  1399 				const XMLCh * baselinealign = FindAttributeValueForType(baselinechildit,KXMLAlignString);
       
  1400 				const XMLCh * currentalign = FindAttributeValueForType(currentchildit,KXMLAlignString);
       
  1401 
       
  1402 				if ( !baselinesize )
       
  1403 				{
       
  1404 					baselinesize = baselinealign;
       
  1405 				}
       
  1406 					
       
  1407 				if ( !currentsize )
       
  1408 				{
       
  1409 					currentsize = currentalign;
       
  1410 				}
       
  1411 
       
  1412 				if ( !Equals(baselinesize,currentsize) || !Equals(baselinealign, currentalign) ||
       
  1413 					!CompareAttributes(baselinechildit,currentchildit,KXMLDefaultString,EOptionalSimpleAttribute))
       
  1414 				{
       
  1415                     ++ret;
       
  1416                     if (report)
       
  1417                     {
       
  1418                         //AddIssue<iFuncType,EIssueTypeParam>(&baseline, current);
       
  1419 						AddIssueFunction<EIssueTypeParam>(&baseline,iFuncType,current,lineNo);
       
  1420                     }
       
  1421                     break;
       
  1422 				}
       
  1423             }
       
  1424 
       
  1425         }
       
  1426 
       
  1427     }
       
  1428 
       
  1429     if ( !CompareAttributes(baseline,current,KXMLReturnsString,EOptionalTypeAttribute) )
       
  1430     {
       
  1431         ++ret;
       
  1432         if (report)
       
  1433         {
       
  1434 			AddIssueFunction<EIssueTypeReturn>(&baseline,iFuncType,current,lineNo);
       
  1435         }
       
  1436     }
       
  1437 
       
  1438     return ret;
       
  1439 }
       
  1440 
       
  1441 
       
  1442 ////////////////////////////////////////////////////////////////////////////////////////
       
  1443 ///////////////////////////////TypedefNodeAnalysis/////////////////////////////////////
       
  1444 
       
  1445 
       
  1446 // ----------------------------------------------------------------------------
       
  1447 // TypedefNodeAnalysis::Construct
       
  1448 // ----------------------------------------------------------------------------
       
  1449 //
       
  1450 NodeAnalysis* TypedefNodeAnalysis::Construct()
       
  1451 {
       
  1452     return new TypedefNodeAnalysis;
       
  1453 }
       
  1454 
       
  1455 // ----------------------------------------------------------------------------
       
  1456 // TypedefNodeAnalysis::FindNodeAndAnalyse
       
  1457 // ----------------------------------------------------------------------------
       
  1458 //
       
  1459 int TypedefNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
  1460 {
       
  1461      DOMNode* node = NodeAnalysis::findNode(baseline,current);
       
  1462     if ( !node )
       
  1463     {
       
  1464         AddIssue<EIssueIdentityTypedef,EIssueTypeRemoval>(&baseline, baseline,0);
       
  1465         return 1;
       
  1466     }
       
  1467     current.current = node;
       
  1468 
       
  1469     return this->Analyse(baseline,current);
       
  1470 }
       
  1471 
       
  1472 // ----------------------------------------------------------------------------
       
  1473 // TypedefNodeAnalysis::Analyse
       
  1474 // ----------------------------------------------------------------------------
       
  1475 //
       
  1476 int TypedefNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
       
  1477 {
       
  1478     assert( Equals(KXMLTypedefString, baseline->getNodeName()) &&
       
  1479     Equals(KXMLTypedefString, current->getNodeName()) &&
       
  1480     Equals(baseline->getNodeName(), current->getNodeName())
       
  1481     );
       
  1482 
       
  1483   //<Typedef id="_9" name="TOmaInt" type="_8" context="_1" location="f0:108" file="f0" line="108"/>
       
  1484 
       
  1485 	int lineNo = 0;
       
  1486 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  1487 	lineNo = atoi(toString(lineNumber).c_str());
       
  1488 
       
  1489     int ret = 0;
       
  1490 
       
  1491     if ( !CompareAttributes(baseline,current,KXMLNameString,ESimpleAttribute) )
       
  1492     {
       
  1493         if (report)
       
  1494         {
       
  1495             AddIssue<EIssueIdentityTypedef,EIssueTypeChange>(&baseline, current,lineNo);
       
  1496         }
       
  1497         ++ret;
       
  1498     }
       
  1499 
       
  1500     if ( !CompareAttributes(baseline,current,KXMLTypeString,ETypeAttribute) )
       
  1501     {
       
  1502         if (report)
       
  1503         {
       
  1504             AddIssue<EIssueIdentityTypedef,EIssueTypeChange>(&baseline, current,lineNo);
       
  1505         }
       
  1506         ++ret;
       
  1507     }
       
  1508 
       
  1509     HANodeIterator baselinetypeit(baseline);
       
  1510     HANodeIterator currenttypeit(current);
       
  1511 
       
  1512     const XMLCh* baselinetypeid = baseline.GetAttribute(KXMLTypeString);
       
  1513     const XMLCh* currenttypeid = current.GetAttribute(KXMLTypeString);
       
  1514 
       
  1515     assert( baselinetypeid && currenttypeid);
       
  1516 
       
  1517     bool ret1 = baselinetypeit.FindNodeById(baselinetypeid);
       
  1518     bool ret2 = currenttypeit.FindNodeById(currenttypeid);
       
  1519 
       
  1520     assert(ret1 && ret2);
       
  1521 
       
  1522 	if ( IsFunction(baselinetypeit) )
       
  1523 	{
       
  1524 		if ( !CompareAttributes(baselinetypeit,currenttypeit,KXMLReturnsString,EOptionalTypeAttribute) )
       
  1525 		{
       
  1526 			if (report)
       
  1527 			{
       
  1528 				AddIssue<EIssueIdentityTypedef,EIssueTypeChange>(&baseline, current,lineNo);
       
  1529 			}
       
  1530 			++ret;
       
  1531 		}
       
  1532 	}
       
  1533 
       
  1534 	if (!CheckAccessModifier(baseline,current))
       
  1535     {
       
  1536         if (report)
       
  1537         {
       
  1538             //AddIssue<iIdentity,EIssueTypeAccess>(&baseline, current);
       
  1539             AddIssue<EIssueIdentityTypedef,EIssueTypeAccess>(&baseline, current,lineNo);
       
  1540         }
       
  1541         ret += 1;
       
  1542     }
       
  1543 
       
  1544     return ret;
       
  1545 }
       
  1546 
       
  1547 
       
  1548 ////////////////////////////////////////////////////////////////////////////////////////
       
  1549 ///////////////////////////////OperatorFunctionNodeAnalysis/////////////////////////////
       
  1550 
       
  1551 // ----------------------------------------------------------------------------
       
  1552 // OperatorFunctionNodeAnalysis::Construct
       
  1553 // ----------------------------------------------------------------------------
       
  1554 //
       
  1555 NodeAnalysis* OperatorFunctionNodeAnalysis::Construct()
       
  1556 {
       
  1557     return new OperatorFunctionNodeAnalysis;
       
  1558 }
       
  1559 
       
  1560 ////////////////////////////////////////////////////////////////////////////////////////
       
  1561 ///////////////////////////////UnionNodeAnalysis////////////////////////////////////////
       
  1562 
       
  1563 // ----------------------------------------------------------------------------
       
  1564 // UnionNodeAnalysis::Construct
       
  1565 // ----------------------------------------------------------------------------
       
  1566 //
       
  1567 NodeAnalysis* UnionNodeAnalysis::Construct()
       
  1568 {
       
  1569     return new UnionNodeAnalysis;
       
  1570 }
       
  1571 
       
  1572 // ----------------------------------------------------------------------------
       
  1573 // UnionNodeAnalysis::UnionNodeAnalysis
       
  1574 // 
       
  1575 // ----------------------------------------------------------------------------
       
  1576 //
       
  1577 UnionNodeAnalysis::UnionNodeAnalysis()
       
  1578 {
       
  1579 	iIdentity = EIssueIdentityUnion;
       
  1580 }
       
  1581 
       
  1582 // ----------------------------------------------------------------------------
       
  1583 // UnionNodeAnalysis::compareBaseSizes
       
  1584 // ----------------------------------------------------------------------------
       
  1585 //
       
  1586 int UnionNodeAnalysis::compareBaseSizes(HANodeIterator baseline, HANodeIterator current, const NodeIndex::dtable_t& bfields, const NodeIndex::dtable_t& cfields, bool report)
       
  1587 {
       
  1588 	//Not meaningful in union as it can not be derived
       
  1589 	return 0;
       
  1590 }
       
  1591 
       
  1592 // ----------------------------------------------------------------------------
       
  1593 // UnionNodeAnalysis::FindNodeAndAnalyse
       
  1594 // ----------------------------------------------------------------------------
       
  1595 //
       
  1596 int UnionNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
  1597 {
       
  1598     //First check to see if this is an anonymous Union
       
  1599     const XMLCh* name = baseline.GetAttribute(KXMLNameString);
       
  1600     if ( !name )
       
  1601     {
       
  1602         //This is anonymous union and does not need to be analysed
       
  1603         return 0;
       
  1604     }
       
  1605     
       
  1606     if ( Equals(name,KXMLEmptyString) )
       
  1607     {
       
  1608         return 0;
       
  1609     }
       
  1610 
       
  1611     DOMNode* node = NodeAnalysis::findNode(baseline,current);
       
  1612 
       
  1613     if ( !node )
       
  1614     {
       
  1615         AddIssue<EIssueIdentityUnion,EIssueTypeRemoval>(&baseline, baseline,0);
       
  1616         return 1;
       
  1617     }
       
  1618     current.current = node;
       
  1619 
       
  1620     return this->Analyse(baseline,current);
       
  1621 }
       
  1622 
       
  1623 // ----------------------------------------------------------------------------
       
  1624 // UnionNodeAnalysis::compareVirtualFunctions
       
  1625 // The union can not have virtual functions
       
  1626 // ----------------------------------------------------------------------------
       
  1627 //
       
  1628 int UnionNodeAnalysis::compareVirtualFunctions(HANodeIterator baseline,HANodeIterator current, 
       
  1629                                                   const vector<DOMNode*>& bvirtualMethods, 
       
  1630 												  const vector<DOMNode*>& cvirtualMethods, 
       
  1631                                                   bool report)
       
  1632 {
       
  1633 	return 0;
       
  1634 }
       
  1635 
       
  1636 ////////////////////////////////////////////////////////////////////////////////////////
       
  1637 ///////////////////////////////ClassNodeAnalysis////////////////////////////////////////
       
  1638 
       
  1639 // ----------------------------------------------------------------------------
       
  1640 // printMember
       
  1641 // Debug stuff
       
  1642 // ----------------------------------------------------------------------------
       
  1643 //
       
  1644 void printMember(HANodeIterator member)
       
  1645 {
       
  1646     DEBUG_PRINT_XMLCh(member->getNodeName());
       
  1647     DEBUG_PRINT(":");
       
  1648     const XMLCh * memname = member.GetAttribute(KXMLNameString);
       
  1649     if (memname)
       
  1650     {
       
  1651         DEBUG_PRINT_XMLCh(memname);
       
  1652     }
       
  1653 }
       
  1654 
       
  1655 // ----------------------------------------------------------------------------
       
  1656 // ClassNodeAnalysis::compareMethodsSignature
       
  1657 // Compare baseline and current methods and return false if they do not match.
       
  1658 // Uses additional comparator object if available.
       
  1659 // ----------------------------------------------------------------------------
       
  1660 //
       
  1661 bool ClassNodeAnalysis::compareMethodsSignature(HANodeIterator basemethod,HANodeIterator currentmethod, const NodeTypeComparator& comparator)
       
  1662 {
       
  1663     short basenodetype = basemethod->getNodeType();
       
  1664     short currnodetype = currentmethod->getNodeType();
       
  1665     assert(basenodetype == DOMNode::ELEMENT_NODE && currnodetype == DOMNode::ELEMENT_NODE);
       
  1666     assert(IsFunction(basemethod) && IsFunction(currentmethod));
       
  1667 
       
  1668 #ifdef _DEBUG
       
  1669     string basefuncsig = GenerateFunctionSignature(basemethod);
       
  1670     string currentfuncsig = GenerateFunctionSignature(currentmethod);
       
  1671     cout << "   basefuncsig=" << basefuncsig << endl;
       
  1672     cout << "currentfuncsig=" << currentfuncsig << endl;
       
  1673 #endif
       
  1674 
       
  1675     if( !Equals(basemethod->getNodeName(), currentmethod->getNodeName() ))
       
  1676     {
       
  1677         return false;
       
  1678     }
       
  1679 
       
  1680     const XMLCh* basenameatt = basemethod.GetAttribute(KXMLNameString);
       
  1681     const XMLCh* currnameatt = currentmethod.GetAttribute(KXMLNameString);
       
  1682 
       
  1683     if( !Equals(basenameatt, currnameatt ))
       
  1684     {
       
  1685         return false;
       
  1686     }
       
  1687 
       
  1688     DOMElement * basenodeelement = static_cast<DOMElement*>(basemethod.current);
       
  1689     DOMElement * currnodeelement = static_cast<DOMElement*>(currentmethod.current);    
       
  1690     std::vector<DOMNode*> baseElementNodes;
       
  1691     std::vector<DOMNode*> currElementNodes;
       
  1692     GetElementNodes(basemethod, basenodeelement->getChildNodes(), baseElementNodes);
       
  1693     GetElementNodes(currentmethod, currnodeelement->getChildNodes(), currElementNodes);    
       
  1694 
       
  1695     if( baseElementNodes.size() != currElementNodes.size() )
       
  1696     {
       
  1697         return false;
       
  1698     }
       
  1699 
       
  1700     for(size_t i = 0; i < baseElementNodes.size(); ++i)
       
  1701     {
       
  1702         DOMNode* basechild = baseElementNodes[i];
       
  1703         DOMNode* currchild = currElementNodes[i];
       
  1704         HANodeIterator basechildit(basemethod);
       
  1705         HANodeIterator currchildit(currentmethod);
       
  1706         basechildit.current = basechild;
       
  1707         currchildit.current = currchild;
       
  1708         
       
  1709         short basetype = basechildit->getNodeType();
       
  1710         short currtype = currchildit->getNodeType();
       
  1711         if( !comparator.CompareParameter(basechildit, currchildit) )
       
  1712         {
       
  1713             return false;
       
  1714         }        
       
  1715     }
       
  1716     
       
  1717     if( !comparator.CompareConstness(basemethod, currentmethod) )
       
  1718     {
       
  1719         return false;
       
  1720     }
       
  1721 
       
  1722     return true;
       
  1723 }
       
  1724 // ----------------------------------------------------------------------------
       
  1725 // ClassNodeAnalysis::compareMethodsReturn
       
  1726 // ----------------------------------------------------------------------------
       
  1727 //
       
  1728 bool ClassNodeAnalysis::compareMethodsReturn(HANodeIterator basemethod,HANodeIterator currentmethod, NodeTypeComparator& cmp) 
       
  1729 {
       
  1730     return cmp.CompareReturnValue(basemethod, currentmethod);
       
  1731 }
       
  1732 
       
  1733 // ----------------------------------------------------------------------------
       
  1734 // ClassNodeAnalysis::compareField
       
  1735 // ----------------------------------------------------------------------------
       
  1736 //
       
  1737 int ClassNodeAnalysis::compareField(HANodeIterator baseline, HANodeIterator current, const DataMember& basemember,const DataMember& currentmember, bool report)
       
  1738 {
       
  1739 	//<!ATTLIST Field mutable (0 | 1) "0">
       
  1740 	//<!ATTLIST Field name CDATA #REQUIRED>
       
  1741 	//<!ATTLIST Field offset CDATA #IMPLIED>
       
  1742 	//<!ATTLIST Field type CDATA #REQUIRED>
       
  1743 	int ret = 0;
       
  1744 
       
  1745 	HANodeIterator basefield(baseline);
       
  1746 	basefield.current = basemember.iNode;
       
  1747 	HANodeIterator currentfield(current);
       
  1748 	currentfield.current = currentmember.iNode;
       
  1749 	
       
  1750 	int baseoffset = basemember.iOffset;
       
  1751     int currentoffset = currentmember.iOffset;
       
  1752 
       
  1753 	TIssueIdentity identity = EIssueIdentityField;
       
  1754 	bool accessthroughinline = false;
       
  1755 
       
  1756 	if ( !CheckAccessibility(baseline,accessthroughinline,basemember.iAccess) )
       
  1757 	{
       
  1758 		identity = EIssueIdentityFieldInaccessible;
       
  1759 	} else
       
  1760 	{
       
  1761 
       
  1762 		if ( baseoffset != currentoffset )
       
  1763 		{
       
  1764 			ret++;
       
  1765 			if ( report )
       
  1766 			{
       
  1767 				AddIssueField<EIssueTypeOffset>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
       
  1768 			}
       
  1769 			else
       
  1770 			{
       
  1771 				return ret;
       
  1772 			}
       
  1773 
       
  1774 		}
       
  1775 	}
       
  1776 
       
  1777 	if ( IsAnonymousType(basefield) )
       
  1778     {
       
  1779         //We need to do comparison between the baseline type and current type anonymously
       
  1780     
       
  1781         HANodeIterator baselinetypeit(basefield);
       
  1782         HANodeIterator currenttypeit(currentfield);
       
  1783 
       
  1784         const XMLCh* baselinetypeid = basefield.GetAttribute(KXMLTypeString);
       
  1785         const XMLCh* currenttypeid = currentfield.GetAttribute(KXMLTypeString);
       
  1786 
       
  1787         assert( baselinetypeid && currenttypeid);
       
  1788 
       
  1789         bool ret1 = baselinetypeit.FindNodeById(baselinetypeid);
       
  1790         bool ret2 = currenttypeit.FindNodeById(currenttypeid);
       
  1791 
       
  1792         assert(ret1 && ret2);
       
  1793 
       
  1794         HANodeIterator baselinetypeanonit(baselinetypeit);
       
  1795         HANodeIterator currenttypeanonit(currenttypeit);
       
  1796         ret1 = FindAnonymousType(baselinetypeit,baselinetypeanonit);
       
  1797         ret2 = FindAnonymousType(currenttypeit,currenttypeanonit);
       
  1798         
       
  1799         assert(ret1);
       
  1800 
       
  1801 		if ( !ret2 || !baselinetypeanonit.IsSameNodeType(currenttypeanonit) )
       
  1802 		{
       
  1803 			if (report)
       
  1804 			{
       
  1805 				AddIssueField<EIssueTypeChangeInType>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
       
  1806 			}
       
  1807 			ret++;
       
  1808 		}
       
  1809 		else
       
  1810 		{
       
  1811 			bool report2 = false;
       
  1812 
       
  1813             if ( Equals(KXMLUnionString, baselinetypeit->getNodeName()) && Equals(KXMLEmptyString, basefield.GetAttribute(KXMLNameString)) )
       
  1814             {
       
  1815                 report2 = report;
       
  1816             }
       
  1817 
       
  1818 			NodeAnalysis::Constructor constructorfunction = FindNodeAnalysisConstructor(baselinetypeanonit->getNodeName());
       
  1819 			NodeAnalysis * analyser = constructorfunction();
       
  1820 			int retval2 = analyser->Analyse(baselinetypeanonit,currenttypeanonit,report2);
       
  1821 			if ( retval2 > 0 && !report2)
       
  1822 			{
       
  1823 				if (report)
       
  1824 				{
       
  1825 					AddIssueField<EIssueTypeChangeInType>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
       
  1826 				}
       
  1827 				++ret;
       
  1828             }
       
  1829             delete analyser;
       
  1830         }
       
  1831     }
       
  1832     else
       
  1833     {
       
  1834         //{KXMLTypeString,EIdAttribute}
       
  1835         if ( !CompareAttributes(basefield,currentfield,KXMLTypeString,ETypeAttribute) )
       
  1836         {
       
  1837 			ret++;
       
  1838 			if ( report )
       
  1839 			{
       
  1840 				AddIssueField<EIssueTypeChangeInType>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
       
  1841 			}
       
  1842 			else
       
  1843 			{
       
  1844 				return ret;
       
  1845 			}
       
  1846 		}else //Check if the size has changed although the the type has remained same
       
  1847 		{
       
  1848 			const XMLCh* basefieldsize = GetSize(basefield);
       
  1849 			const XMLCh* currentfieldsize = GetSize(currentfield);
       
  1850 
       
  1851 			if ( !Equals(basefieldsize,currentfieldsize) )
       
  1852 			{
       
  1853 				ret++;
       
  1854 				if ( report )
       
  1855 				{
       
  1856 					AddIssueField<EIssueTypeSize>(&baseline,identity, currentfield,currentmember.iLineNo,NULL,basemember);
       
  1857 				}
       
  1858 				else
       
  1859 				{
       
  1860 					return ret;
       
  1861 				}
       
  1862 			}
       
  1863 
       
  1864 		}
       
  1865     }
       
  1866     return ret;
       
  1867 }
       
  1868 
       
  1869 // ----------------------------------------------------------------------------
       
  1870 // dumpNodeVectordumpNodeVector
       
  1871 // ----------------------------------------------------------------------------
       
  1872 //
       
  1873 void dumpNodeVector(HANodeIterator node,const vector<DOMNode*> & nodes)
       
  1874 {
       
  1875     DEBUG_PRINT("Dumping node vector:\n")
       
  1876     vector<DOMNode*>::const_iterator it = nodes.begin();
       
  1877     for (;it != nodes.end(); ++it)
       
  1878     {
       
  1879         node.current = (*it);
       
  1880 
       
  1881         DEBUG_PRINT_XMLCh(node->getNodeName())
       
  1882         const XMLCh * name = node.GetAttribute(KXMLNameString);
       
  1883         if (name)
       
  1884         {
       
  1885         DEBUG_PRINT(":")
       
  1886         DEBUG_PRINT_XMLCh(name)
       
  1887         }
       
  1888         const XMLCh * id = node.GetAttribute(KXMLIdString);
       
  1889         if (id)
       
  1890         {
       
  1891         DEBUG_PRINT(" with id ")
       
  1892         DEBUG_PRINT_XMLCh(id)
       
  1893         }
       
  1894         DEBUG_PRINT("\n")
       
  1895     }
       
  1896 }
       
  1897 
       
  1898 // ----------------------------------------------------------------------------
       
  1899 // ClassNodeAnalysis::compareNonvirtualFunctions
       
  1900 // ----------------------------------------------------------------------------
       
  1901 //
       
  1902 int ClassNodeAnalysis::compareNonvirtualFunctions( HANodeIterator baseline,
       
  1903                                                     HANodeIterator current, 
       
  1904                                                     const vector<DOMNode*>& bexportedMethods,
       
  1905                                                     const vector<DOMNode*>& cexportedMethods,
       
  1906                                                     TIssueIdentity identity,
       
  1907                                                     bool report )
       
  1908 {
       
  1909     int ret = 0;
       
  1910 	int parentLineNo = 0;
       
  1911 
       
  1912     // Get default comparator:
       
  1913     const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();       
       
  1914     ComparatorVector::const_iterator comparator = cmps.begin();
       
  1915 	const XMLCh* parenLinenumber = current.GetAttribute( KXMLLineString);
       
  1916 	parentLineNo = atoi(toString(parenLinenumber).c_str());
       
  1917 
       
  1918     // Build method maps for baseline and current platform's classes:
       
  1919     MethodMatchMap baseMap;    
       
  1920     vector<DOMNode*>::const_iterator i = bexportedMethods.begin();
       
  1921     for( ; i != bexportedMethods.end(); ++i )
       
  1922     {
       
  1923         baseMap.insert( make_pair(*i, MethodMatchFlags(false, false)));
       
  1924     }
       
  1925 
       
  1926     vector<DOMNode*>::const_iterator j = cexportedMethods.begin();
       
  1927     MethodMatchMap currMap;    
       
  1928     for( ; j != cexportedMethods.end(); ++j )
       
  1929     {
       
  1930         currMap.insert( make_pair(*j, MethodMatchFlags(false, false)));
       
  1931     }
       
  1932 
       
  1933     if( comparator != cmps.end() )
       
  1934     {
       
  1935         int comparatorRound = 1;
       
  1936         // Call compare function and give the default comparator as a parameter
       
  1937         ret = this->compareNonvirtualFunctions(baseline, current, bexportedMethods, cexportedMethods, identity, report, comparator, baseMap, currMap, comparatorRound);        
       
  1938     }
       
  1939 
       
  1940     if( report )
       
  1941     {
       
  1942         MethodMatchMap::iterator baseFunc = baseMap.begin();
       
  1943         for(; baseFunc != baseMap.end(); ++baseFunc )
       
  1944         {
       
  1945 			int lineNo = 0;
       
  1946 			string baseMethodName = toString(GetAttribute(baseFunc->first,KXMLNameString));
       
  1947 			MethodMatchMap::iterator curFunc = currMap.begin();
       
  1948 			for(; curFunc != currMap.end(); ++curFunc )
       
  1949 			{
       
  1950 				string curMethodName = toString(GetAttribute(curFunc->first,KXMLNameString));
       
  1951 				if (baseMethodName == curMethodName)
       
  1952 				{
       
  1953 					const XMLCh* linenumber = GetAttribute(curFunc->first, KXMLLineString);
       
  1954 					lineNo = atoi(toString(linenumber).c_str());
       
  1955 					break;
       
  1956 
       
  1957 				}
       
  1958 			}
       
  1959             if( baseFunc->second.signatureMatch == false )
       
  1960             {
       
  1961                 // Function signatures do not match
       
  1962                 HANodeIterator removedMethod(baseline);
       
  1963                 removedMethod.current = baseFunc->first;
       
  1964                 AddIssueFunction<EIssueTypeRemoval>(&removedMethod, identity, removedMethod,parentLineNo);            
       
  1965                 ++ret;
       
  1966             }
       
  1967             else if( baseFunc->second.returnValueMatch == false )
       
  1968 			{
       
  1969 				// Function return values do not match
       
  1970 				HANodeIterator removedMethod(baseline);
       
  1971 				removedMethod.current = baseFunc->first;
       
  1972 				AddIssueFunction<EIssueTypeReturn>(&removedMethod,identity, removedMethod,lineNo);                
       
  1973 				++ret;
       
  1974 			}
       
  1975         }
       
  1976     }
       
  1977     return ret;
       
  1978 }
       
  1979 // ----------------------------------------------------------------------------
       
  1980 // ClassNodeAnalysis::compareNonvirtualFunctions
       
  1981 // ----------------------------------------------------------------------------
       
  1982 //
       
  1983 int ClassNodeAnalysis::compareNonvirtualFunctions(
       
  1984         HANodeIterator baseline,
       
  1985         HANodeIterator current, 
       
  1986         const vector<DOMNode*>& bexportedMethods,
       
  1987         const vector<DOMNode*>& cexportedMethods,
       
  1988         TIssueIdentity identity,                                          
       
  1989         bool report,
       
  1990         ComparatorVector::const_iterator comparator,
       
  1991         MethodMatchMap& baseMap,
       
  1992         MethodMatchMap& currMap,
       
  1993 		int comparatorRound)
       
  1994 {
       
  1995     int ret = 0;
       
  1996 
       
  1997 	int lineNo1 = 0;
       
  1998 	//const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  1999 	//lineNo = atoi(toString(lineNumber).c_str());
       
  2000 
       
  2001 	//Exported methods    
       
  2002 	vector<DOMNode*>::const_iterator bIter = bexportedMethods.begin();        
       
  2003 	for( ; bIter != bexportedMethods.end(); ++bIter )
       
  2004 	{
       
  2005 		MethodMatchMap::iterator baseMapIter = baseMap.find(*bIter);
       
  2006 		assert(baseMapIter != baseMap.end());
       
  2007 		if( baseMapIter->second.signatureMatch )
       
  2008 		{
       
  2009 			continue; // This method has already been found and analyzed.
       
  2010 		}
       
  2011 		HANodeIterator basemethod(baseline);        
       
  2012 		basemethod.current = *bIter;
       
  2013 
       
  2014 		//Check the accessibility
       
  2015 		if ( CheckAccessibility(basemethod) )
       
  2016 		{            
       
  2017 			vector<DOMNode*>::const_iterator cIter = cexportedMethods.begin();   
       
  2018 
       
  2019 			for( ; cIter != cexportedMethods.end(); ++cIter)            
       
  2020 			{                
       
  2021 				HANodeIterator currentmethod(current);
       
  2022 				currentmethod.current = *cIter;
       
  2023 				const XMLCh* lineNumber1 = GetAttribute(currentmethod.current,KXMLLineString);
       
  2024 				lineNo1 = atoi(toString(lineNumber1).c_str());
       
  2025 
       
  2026 				MethodMatchMap::iterator currMapIter = currMap.find(*cIter);
       
  2027 
       
  2028                 if( currMapIter != currMap.end() && 
       
  2029                     currMapIter->second.signatureMatch == false &&
       
  2030                     compareMethodsSignature(basemethod, currentmethod, **comparator) )
       
  2031                 {                    
       
  2032                     if( comparatorRound==CONSTFILTER_COMPARATOR )
       
  2033                     {                        
       
  2034                         // if one of the parameter has changed from non-const to const
       
  2035                         ret++;
       
  2036                         if(report)
       
  2037                         {
       
  2038                             //add the issue as it is a source compatibility break
       
  2039                             AddIssueFunction<EIssueTypeParamConst>(&basemethod,identity,currentmethod,lineNo1);
       
  2040                         }
       
  2041                         
       
  2042                         //make signature and return value true so that the issue is not reported again
       
  2043                         if( baseMapIter != baseMap.end() )
       
  2044                             baseMapIter->second.signatureMatch = true;
       
  2045                         currMapIter->second.signatureMatch = true;
       
  2046                         
       
  2047                         baseMapIter->second.returnValueMatch = true;
       
  2048                         currMapIter->second.returnValueMatch = true;
       
  2049                         break;
       
  2050                     }
       
  2051                     
       
  2052                     else if( comparatorRound==CONSTFILTER2_COMPARATOR )
       
  2053                     {                        
       
  2054                         // if one of the parameter has changed from const to non-const
       
  2055                         ret++;
       
  2056                         if(report)
       
  2057                         {
       
  2058                             //add the issue as it is a source compatibility break
       
  2059 							AddIssueFunction<EIssueTypeParamConst2>(&basemethod,identity,currentmethod,lineNo1);
       
  2060                         }
       
  2061                         
       
  2062                         //make signature and return value true so that the issue is not reported again
       
  2063                         if( baseMapIter != baseMap.end() )
       
  2064                             baseMapIter->second.signatureMatch = true;
       
  2065                         currMapIter->second.signatureMatch = true;
       
  2066                         
       
  2067                         baseMapIter->second.returnValueMatch = true;
       
  2068                         currMapIter->second.returnValueMatch = true;
       
  2069                         break;
       
  2070                     }
       
  2071                     
       
  2072                     if( baseMapIter != baseMap.end() )
       
  2073                         baseMapIter->second.signatureMatch = true;
       
  2074                     currMapIter->second.signatureMatch = true;
       
  2075                     //Check also the default parameter values
       
  2076                     DOMElement * baselineelement = static_cast<DOMElement*>(basemethod.current);
       
  2077                     DOMNodeList* baselinechilds = baselineelement->getChildNodes();
       
  2078                     DOMElement * currentelement = static_cast<DOMElement*>(currentmethod.current);
       
  2079                     DOMNodeList* currentchilds = currentelement->getChildNodes();
       
  2080                         
       
  2081                     XMLSize_t childcount = baselinechilds->getLength();
       
  2082                     
       
  2083                     unsigned int i = 0;
       
  2084                     for (i = 0; i < childcount; ++i)
       
  2085                     {
       
  2086                         DOMNode* baselinechild = baselinechilds->item(i);
       
  2087                         HANodeIterator baselinechildit(baseline);
       
  2088                         baselinechildit.current = baselinechild;
       
  2089                          
       
  2090                         DOMNode* currentchild = currentchilds->item(i);
       
  2091                         HANodeIterator currentchildit(current);
       
  2092                         currentchildit.current = currentchild;
       
  2093                                 
       
  2094                         short nodetype = baselinechildit->getNodeType();
       
  2095                         if (nodetype == DOMNode::ELEMENT_NODE)
       
  2096                         {
       
  2097                             const XMLCh * baselinesize = FindAttributeValueForType(baselinechildit,KXMLSizeString);
       
  2098                             const XMLCh * currentsize = FindAttributeValueForType(currentchildit,KXMLSizeString);
       
  2099                                
       
  2100                             const XMLCh * baselinealign = FindAttributeValueForType(baselinechildit,KXMLAlignString);
       
  2101                             const XMLCh * currentalign = FindAttributeValueForType(currentchildit,KXMLAlignString);
       
  2102                                   
       
  2103                             if ( !baselinesize )
       
  2104                             {
       
  2105                                 baselinesize = baselinealign;
       
  2106                             }
       
  2107                                  
       
  2108                             if ( !currentsize )
       
  2109                             {
       
  2110                                 currentsize = currentalign;
       
  2111                             }
       
  2112                                  
       
  2113                             if ( !Equals(baselinesize,currentsize) || !Equals(baselinealign, currentalign) ||
       
  2114                                  !CompareAttributes(baselinechildit,currentchildit,KXMLDefaultString,EOptionalSimpleAttribute))
       
  2115                             {
       
  2116                                  ++ret;
       
  2117                                  if (report)
       
  2118                                  {
       
  2119 									AddIssueFunction<EIssueTypeParam>(&basemethod,identity,currentmethod,lineNo1);
       
  2120                                  }
       
  2121                                  break;
       
  2122                             }
       
  2123                         }
       
  2124                     }
       
  2125                     
       
  2126                     // Check function return values
       
  2127                     const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();       
       
  2128                     ComparatorVector::const_iterator retComparator = cmps.begin();
       
  2129                     int retComparatorRound = 1;
       
  2130                     for ( ; retComparator != cmps.end(); retComparator++ )
       
  2131                     {
       
  2132                         if ( compareMethodsReturn(basemethod,currentmethod, **retComparator) )
       
  2133                         { 
       
  2134                             if( retComparatorRound==CONSTFILTER_COMPARATOR )
       
  2135                             {                       
       
  2136                                 // if the return value has changed from const to non-const
       
  2137                                 ret++;
       
  2138                                 if(report)
       
  2139                                 {
       
  2140                                     //add the issue as it is a source compatibility break
       
  2141 									AddIssueFunction<EIssueTypeReturnConst>(&basemethod,identity,currentmethod,lineNo1);
       
  2142                                 }
       
  2143                             }
       
  2144                             else if( retComparatorRound==CONSTFILTER2_COMPARATOR )
       
  2145                             {                       
       
  2146                                 // if the return calue has changed from non-const to const
       
  2147                                 ret++;
       
  2148                                 if(report)
       
  2149                                 {
       
  2150                                     //add the issue as it is a source compatibility break
       
  2151 									AddIssueFunction<EIssueTypeReturnConst2>(&basemethod,identity,currentmethod,lineNo1);
       
  2152                                 }
       
  2153                             }         
       
  2154                             
       
  2155                             baseMapIter->second.returnValueMatch = true;
       
  2156                             currMapIter->second.returnValueMatch = true;
       
  2157                             break;
       
  2158                         }
       
  2159                         retComparatorRound++;
       
  2160                     }
       
  2161                     
       
  2162                                     
       
  2163                     if ( !CheckAccessModifier(basemethod,currentmethod) )
       
  2164                     {
       
  2165                         if (report)
       
  2166                         {
       
  2167 							AddIssueFunction<EIssueTypeAccess>(&basemethod,identity, currentmethod,lineNo1);
       
  2168                         }
       
  2169                         ++ret;
       
  2170                     }
       
  2171                     break;
       
  2172                 }
       
  2173             }
       
  2174         }
       
  2175         else
       
  2176         {
       
  2177             // Not accessible, can be marked as matching.
       
  2178             if( baseMapIter != baseMap.end() )
       
  2179             {
       
  2180                 baseMapIter->second.signatureMatch = true;
       
  2181                 baseMapIter->second.returnValueMatch = true;
       
  2182             }
       
  2183         }
       
  2184     }
       
  2185         
       
  2186     // Recursive call with next comparator (if any) and updated method maps.
       
  2187     const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();
       
  2188     if( ++comparator != cmps.end() )
       
  2189     {
       
  2190         comparatorRound++;
       
  2191         ret += ClassNodeAnalysis::compareNonvirtualFunctions(
       
  2192             baseline,
       
  2193             current, 
       
  2194             bexportedMethods,        
       
  2195             cexportedMethods,                                           
       
  2196             identity,                                          
       
  2197             report,
       
  2198             comparator,
       
  2199             baseMap,
       
  2200             currMap,
       
  2201             comparatorRound);
       
  2202     }
       
  2203     
       
  2204     return ret;
       
  2205 }
       
  2206 
       
  2207 // ----------------------------------------------------------------------------
       
  2208 // ClassNodeAnalysis::compareOthers
       
  2209 // ----------------------------------------------------------------------------
       
  2210 //
       
  2211 int ClassNodeAnalysis::compareOthers(HANodeIterator baseline,HANodeIterator current, 
       
  2212                                      const vector<DOMNode*>& bothers, const vector<DOMNode*>& cothers, 
       
  2213                                      bool report)
       
  2214 {
       
  2215 	int retval = 0;
       
  2216 	return retval;
       
  2217 }
       
  2218 
       
  2219 // ----------------------------------------------------------------------------
       
  2220 // printlist
       
  2221 // ----------------------------------------------------------------------------
       
  2222 //
       
  2223 void printlist(const NodeIndex::dtable_t& lista)
       
  2224 {
       
  2225 	NodeIndex::dtable_t::const_iterator it = lista.begin();
       
  2226 	for (; it != lista.end(); ++it)
       
  2227 	{
       
  2228 		cout << it->iName << " at " << it->iOffset << "with node:" << it->iNode <<  endl;
       
  2229 	}
       
  2230 }
       
  2231 
       
  2232 // ----------------------------------------------------------------------------
       
  2233 // ClassNodeAnalysis::compareFields
       
  2234 // ----------------------------------------------------------------------------
       
  2235 //
       
  2236 int ClassNodeAnalysis::compareFields(HANodeIterator baseline,HANodeIterator current,
       
  2237                                      const vector<DOMNode*>& bfields_class,
       
  2238 									 const vector<DOMNode*>& cfields_class,
       
  2239                                      bool report)
       
  2240 {
       
  2241 	int ret = 0;
       
  2242 
       
  2243 	const NodeIndex::dtable_t& bfields = ClassGenerateDataMemberTable(baseline);
       
  2244 	const NodeIndex::dtable_t& cfields = ClassGenerateDataMemberTable(current);
       
  2245 
       
  2246 	int lineNo = 0;
       
  2247 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  2248 	lineNo = atoi(toString(lineNumber).c_str());
       
  2249 
       
  2250 	// If you don't like to see the issue about base size when the size has changed
       
  2251 	// uncomment the test below
       
  2252 
       
  2253 	//if (!iReportAddedMembers)
       
  2254 	//{
       
  2255 		// Check only if size has not changed
       
  2256 		ret += compareBaseSizes(baseline, current, bfields, cfields, report);
       
  2257 	//}
       
  2258 
       
  2259 	// Fields
       
  2260     // Order and type of accessible members matters
       
  2261     //////////////////////////////////////////////////////////////
       
  2262     vector<bool> fieldFound(cfields.size(),false);
       
  2263     vector<bool> fieldRemoved(bfields.size(),false);
       
  2264     vector<bool> fieldChanged(bfields.size(),false);
       
  2265     vector<int> fieldChangedCurrent(bfields.size(),-1);
       
  2266     vector<bool> fieldAccessible(bfields.size(),false);
       
  2267 
       
  2268 	unsigned int i = 0;
       
  2269     for (i=0; i < bfields.size(); ++i)
       
  2270     {
       
  2271 		if ( !bfields[i].iNode )
       
  2272 		{
       
  2273 			unsigned int ii = 0;
       
  2274 			for (ii=0; ii < cfields.size(); ++ii)
       
  2275 			{
       
  2276 				if ( !fieldFound[ii] && (bfields[i].iName == cfields[ii].iName) )
       
  2277 				{
       
  2278 	                fieldFound[ii] = true;
       
  2279 
       
  2280 					if ( bfields[i].iOffset != cfields[ii].iOffset )
       
  2281 					{
       
  2282 						if (report)
       
  2283 						{
       
  2284 							AddIssue<EIssueIdentityVirtualTablePointer,EIssueTypeOffset>(&baseline,current,lineNo,NULL,bfields[i]);							
       
  2285 						}
       
  2286 						++ret;
       
  2287 					}
       
  2288 					break;
       
  2289 				}
       
  2290 			}
       
  2291 
       
  2292 			if ( cfields.size() == ii )
       
  2293 			{
       
  2294 				fieldRemoved[i] = true;
       
  2295 			}
       
  2296 
       
  2297 			continue;
       
  2298 		}
       
  2299 
       
  2300         HANodeIterator basefield(baseline);
       
  2301         basefield.current = bfields[i].iNode;
       
  2302 		bool dummy;
       
  2303  		fieldAccessible[i] = CheckAccessibility(baseline, dummy, bfields[i].iAccess);
       
  2304 
       
  2305         unsigned int ii = 0;
       
  2306         for (ii=0; ii < cfields.size(); ++ii)
       
  2307         {
       
  2308             HANodeIterator currentfield(current);
       
  2309             currentfield.current = cfields[ii].iNode;
       
  2310             
       
  2311             if ( !fieldFound[ii] && (bfields[i].iName == cfields[ii].iName) )//CompareNames(basefield,currentfield) )
       
  2312             {
       
  2313                 fieldFound[ii] = true;
       
  2314 
       
  2315                 if ( fieldAccessible[i] && !CheckAccessModifier(bfields[i].iAccess,cfields[ii].iAccess) )
       
  2316                 {
       
  2317                     if (report)
       
  2318                     {
       
  2319                         AddIssue<EIssueIdentityField,EIssueTypeAccess>(&baseline, currentfield,cfields[ii].iLineNo,NULL,bfields[i]);
       
  2320                     }
       
  2321                     ++ret;
       
  2322                 }
       
  2323 
       
  2324 				if ( 0 != compareField(baseline,current,bfields[i],cfields[ii],false) )
       
  2325                 {
       
  2326 					fieldChanged[i] = true;
       
  2327 					fieldChangedCurrent[i] = ii;
       
  2328 					if (fieldAccessible[i])
       
  2329 					{
       
  2330 						iReportAddedMembers = true;
       
  2331 					}
       
  2332                 }
       
  2333                 break;
       
  2334             }
       
  2335         }
       
  2336 
       
  2337         if ( cfields.size() == ii )
       
  2338         {
       
  2339 			fieldRemoved[i] = true;
       
  2340             if ( fieldAccessible[i] )
       
  2341             {
       
  2342 				iReportAddedMembers = true;
       
  2343             }
       
  2344         }
       
  2345     }
       
  2346 
       
  2347     for (i = 0; i < fieldRemoved.size(); ++i)
       
  2348     {
       
  2349         if (fieldRemoved[i])
       
  2350         {
       
  2351 			if ( !bfields[i].iNode )
       
  2352 			{
       
  2353 				if (report)
       
  2354 				{
       
  2355 					AddIssue<EIssueIdentityVirtualTablePointer,EIssueTypeRemoval>(&baseline,current,lineNo,NULL,bfields[i]);							
       
  2356 				}
       
  2357 				continue;
       
  2358 			}
       
  2359 
       
  2360             HANodeIterator basefield(baseline);
       
  2361             basefield.current = bfields[i].iNode;
       
  2362 
       
  2363 			if (iReportAddedMembers || fieldAccessible[i])
       
  2364 			{
       
  2365 				if (report)
       
  2366 				{
       
  2367 					if (fieldAccessible[i])
       
  2368 					{
       
  2369 						AddIssue<EIssueIdentityField,EIssueTypeRemoval>(&baseline, basefield,lineNo,NULL,bfields[i]);
       
  2370 					}
       
  2371 					else
       
  2372 					{
       
  2373 						AddIssue<EIssueIdentityFieldInaccessible,EIssueTypeRemoval>(&baseline, basefield,lineNo,NULL,bfields[i]);
       
  2374 					}
       
  2375 				}
       
  2376 				++ret;
       
  2377 			}
       
  2378         }
       
  2379 
       
  2380         if (fieldChanged[i])
       
  2381         {
       
  2382             HANodeIterator basefield(baseline);
       
  2383             HANodeIterator currentfield(current);
       
  2384             basefield.current = bfields[i].iNode;
       
  2385 			int ii = fieldChangedCurrent[i];
       
  2386 
       
  2387 			if ( -1 == ii )
       
  2388 			{
       
  2389 				continue;
       
  2390 			}
       
  2391 
       
  2392 			if (iReportAddedMembers || fieldAccessible[i])
       
  2393 			{
       
  2394 				if (report)
       
  2395 				{
       
  2396 					compareField(baseline, current, bfields[i], cfields[ii], report);
       
  2397 				}
       
  2398 				++ret;
       
  2399 			}
       
  2400         }
       
  2401 
       
  2402     }
       
  2403 
       
  2404     for (i = 0; i < fieldFound.size(); ++i)
       
  2405     {
       
  2406         if (!fieldFound[i])
       
  2407         {
       
  2408  			if ( !cfields[i].iNode )
       
  2409 			{
       
  2410 				if (report)
       
  2411 				{
       
  2412 					AddIssue<EIssueIdentityVirtualTablePointer,EIssueTypeAddition>(&baseline,current,lineNo,NULL,cfields[i]);							
       
  2413 				}
       
  2414 				continue;
       
  2415 			}
       
  2416 
       
  2417 			HANodeIterator currentfield(current);
       
  2418             currentfield.current = cfields[i].iNode;
       
  2419             if (report && iReportAddedMembers)
       
  2420             {
       
  2421                 AddIssue<EIssueIdentityField,EIssueTypeAddition>(&current, currentfield,cfields[i].iLineNo,NULL,cfields[i]);
       
  2422             }
       
  2423             ++ret;
       
  2424         }
       
  2425     }
       
  2426 	return ret;
       
  2427 }
       
  2428 
       
  2429 // ----------------------------------------------------------------------------
       
  2430 // printlist
       
  2431 // Output list members
       
  2432 // 
       
  2433 // ----------------------------------------------------------------------------
       
  2434 //
       
  2435 void printlist(const NodeIndex::vtable_t& lista)
       
  2436 {
       
  2437 	NodeIndex::vtable_t::const_iterator it = lista.begin();
       
  2438 	for (; it != lista.end(); ++it)
       
  2439 	{
       
  2440 		cout << it->first << endl;
       
  2441 	}
       
  2442 
       
  2443 }
       
  2444 
       
  2445 // ----------------------------------------------------------------------------
       
  2446 // ClassNodeAnalysis::indexVirtualMethods
       
  2447 // ----------------------------------------------------------------------------
       
  2448 //
       
  2449 void ClassNodeAnalysis::indexVirtualMethods(HANodeIterator node, 
       
  2450 											const vector<DOMNode*>& virtualMethods, 
       
  2451 											const NodeIndex::vtable_t& vtable,
       
  2452 											vector<pair<DOMNode*,int> >& virtualMethodsWithIndex)
       
  2453 {
       
  2454 	vector<DOMNode*>::const_iterator it = virtualMethods.begin();
       
  2455 
       
  2456 	for (; it != virtualMethods.end(); ++it)
       
  2457 	{	
       
  2458 		NodeIndex::vtable_t::const_iterator vtableit = vtable.begin();
       
  2459 		for (int i = 0; vtableit != vtable.end(); ++vtableit, ++i)
       
  2460 		{
       
  2461 			HANodeIterator funcnode(node);
       
  2462 			funcnode.current = *it;
       
  2463 
       
  2464 			char index_str[256];
       
  2465 
       
  2466 			sprintf(index_str, "%d",i);
       
  2467 			
       
  2468 			funcnode.SetAttribute(KXMLBBCVirtualFunctionIndex, index_str );
       
  2469 
       
  2470 			string funcsig = GenerateFunctionSignature(funcnode);
       
  2471 			if (funcsig == vtableit->first)
       
  2472 			{
       
  2473 				virtualMethodsWithIndex.push_back(pair<DOMNode*,int>(*it,i));
       
  2474 			}
       
  2475 		}
       
  2476 	}
       
  2477 }
       
  2478 
       
  2479 // ----------------------------------------------------------------------------
       
  2480 // ClassNodeAnalysis::compareVirtualTables
       
  2481 // ----------------------------------------------------------------------------
       
  2482 //
       
  2483 int ClassNodeAnalysis::compareVirtualTables(HANodeIterator baseline,HANodeIterator current,
       
  2484 											const NodeIndex::vtable_t& basevtable, 
       
  2485 											const NodeIndex::vtable_t& currentvtable,
       
  2486                                             bool report)
       
  2487 {
       
  2488 	if ( basevtable.size() != currentvtable.size() )
       
  2489 	{
       
  2490 		return 1;
       
  2491 	}
       
  2492 
       
  2493 	NodeIndex::vtable_t::const_iterator baseit = basevtable.begin();
       
  2494 	NodeIndex::vtable_t::const_iterator currentit = currentvtable.begin();
       
  2495 
       
  2496 	unsigned int i = 0;
       
  2497     for (i=0; baseit != basevtable.end(); ++baseit,++i,++currentit)
       
  2498     {
       
  2499 
       
  2500         if ( baseit->first != currentit->first )
       
  2501 		{
       
  2502 			return 1;
       
  2503 		}
       
  2504     }
       
  2505 	return 0;
       
  2506 }
       
  2507 
       
  2508 // ----------------------------------------------------------------------------
       
  2509 // ClassNodeAnalysis::compareVirtualFunctions
       
  2510 // ----------------------------------------------------------------------------
       
  2511 //
       
  2512 int ClassNodeAnalysis::compareVirtualFunctions(HANodeIterator baseline,HANodeIterator current, 
       
  2513                                                   const vector<DOMNode*>& bvirtualMethods, 
       
  2514 												  const vector<DOMNode*>& cvirtualMethods, 
       
  2515                                                   bool report)
       
  2516 {
       
  2517 	int ret = 0;
       
  2518 	//Analyse virtual methods, not a single change is tolerated
       
  2519 
       
  2520     // First we build virtual tables for baseline and current classes.
       
  2521 	const NodeIndex::vtable_t& basevtable = ClassGenerateVirtualTable(baseline);
       
  2522 	const NodeIndex::vtable_t& currentvtable = ClassGenerateVirtualTable(current);
       
  2523 
       
  2524 	int parentLineNo = 0;
       
  2525 	int lineNo = 0;
       
  2526 	const XMLCh* parentlineNumber = current.GetAttribute(KXMLLineString);
       
  2527 	parentLineNo = atoi(toString(parentlineNumber).c_str());
       
  2528 
       
  2529 	if ( 0 != compareVirtualTables(baseline,current,basevtable,currentvtable,report) )
       
  2530 	{
       
  2531         // Virtual table has been changed.
       
  2532 		AddIssue<EIssueIdentityVirtualTable,EIssueTypeChange>(&baseline, current, parentLineNo, NULL, "[Primary-vtable]");	
       
  2533 	}
       
  2534 
       
  2535 	vector<pair<DOMNode*,int> > bvirtualMethodsWithIndex;
       
  2536 	vector<pair<DOMNode*,int> > cvirtualMethodsWithIndex;
       
  2537 
       
  2538     // Add virtual methods to vectors with their indexes (i.e. order inside a class).
       
  2539 	indexVirtualMethods(baseline,bvirtualMethods,basevtable,bvirtualMethodsWithIndex);
       
  2540 	indexVirtualMethods(current,cvirtualMethods,currentvtable,cvirtualMethodsWithIndex);
       
  2541 
       
  2542     unsigned int i = 0;
       
  2543     vector<bool> virtualMethodFound(cvirtualMethodsWithIndex.size(),false);
       
  2544 
       
  2545     // Use only default comparator here, since virtual functions should have strict match.
       
  2546     const ComparatorVector& cmps = ComparatorFactory::Instance().GetComparators();
       
  2547     ComparatorVector::const_iterator defaultcomparator = cmps.begin();
       
  2548     assert( defaultcomparator != cmps.end() );
       
  2549 
       
  2550     for (i=0; i < bvirtualMethodsWithIndex.size(); ++i)
       
  2551     {
       
  2552         HANodeIterator basemethod(baseline);
       
  2553         basemethod.current = bvirtualMethodsWithIndex[i].first;
       
  2554 
       
  2555         unsigned int ii = 0;
       
  2556         for (ii=0; ii < cvirtualMethodsWithIndex.size(); ++ii)
       
  2557         {
       
  2558             HANodeIterator currentmethod(current);
       
  2559             currentmethod.current = cvirtualMethodsWithIndex[ii].first;
       
  2560             
       
  2561 			lineNo = 0;
       
  2562 			const XMLCh* lineNumber = currentmethod.GetAttribute(KXMLLineString);
       
  2563 			lineNo = atoi(toString(lineNumber).c_str());
       
  2564                 if ( compareMethodsSignature(basemethod,currentmethod, **defaultcomparator) )
       
  2565             {
       
  2566                 virtualMethodFound[ii] = true;
       
  2567                 if (bvirtualMethodsWithIndex[i].second != cvirtualMethodsWithIndex[ii].second)
       
  2568                 {
       
  2569                     // Here the indexes don't match --> The order of virtual methods has been
       
  2570                     // changed. This means that the layout of the virtual table has been changed
       
  2571                     // and the binary compatibility is broken.
       
  2572                     if (report)
       
  2573                     {
       
  2574 						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeOrderChange>(&basemethod, currentmethod,lineNo);
       
  2575 					}
       
  2576                     ++ret;
       
  2577                 }
       
  2578 
       
  2579 				//Check also the default parameter values
       
  2580 				DOMElement * baselineelement = static_cast<DOMElement*>(basemethod.current);
       
  2581 				DOMNodeList* baselinechilds = baselineelement->getChildNodes();
       
  2582 				DOMElement * currentelement = static_cast<DOMElement*>(currentmethod.current);
       
  2583 				DOMNodeList* currentchilds = currentelement->getChildNodes();
       
  2584 			    
       
  2585 				XMLSize_t childcount = baselinechilds->getLength();
       
  2586 
       
  2587 				unsigned int i = 0;
       
  2588 				for (i = 0; i < childcount; ++i)
       
  2589 				{
       
  2590 					DOMNode* baselinechild = baselinechilds->item(i);
       
  2591 					HANodeIterator baselinechildit(baseline);
       
  2592 					baselinechildit.current = baselinechild;
       
  2593 
       
  2594 					DOMNode* currentchild = currentchilds->item(i);
       
  2595 					HANodeIterator currentchildit(current);
       
  2596 					currentchildit.current = currentchild;
       
  2597 
       
  2598 					short nodetype = baselinechildit->getNodeType();
       
  2599 					if (nodetype == DOMNode::ELEMENT_NODE)
       
  2600 					{
       
  2601 						const XMLCh * baselinesize = FindAttributeValueForType(baselinechildit,KXMLSizeString);
       
  2602 						const XMLCh * currentsize = FindAttributeValueForType(currentchildit,KXMLSizeString);
       
  2603 
       
  2604 						const XMLCh * baselinealign = FindAttributeValueForType(baselinechildit,KXMLAlignString);
       
  2605 						const XMLCh * currentalign = FindAttributeValueForType(currentchildit,KXMLAlignString);
       
  2606 
       
  2607 						if ( !baselinesize )
       
  2608 						{
       
  2609 							baselinesize = baselinealign;
       
  2610 						}
       
  2611 							
       
  2612 						if ( !currentsize )
       
  2613 						{
       
  2614 							currentsize = currentalign;
       
  2615 						}
       
  2616 
       
  2617 						if ( !Equals(baselinesize,currentsize) || !Equals(baselinealign, currentalign) ||
       
  2618 							!CompareAttributes(baselinechildit,currentchildit,KXMLDefaultString,EOptionalSimpleAttribute))
       
  2619 						{
       
  2620 							++ret;
       
  2621 							if (report)
       
  2622 							{
       
  2623 								AddIssue<EIssueIdentityVirtualFunction,EIssueTypeParam>(&basemethod,currentmethod, lineNo);
       
  2624 							}
       
  2625 							break;
       
  2626 						}
       
  2627 					}
       
  2628 				}					
       
  2629                 // check the return types of the methods
       
  2630 				if ( !compareMethodsReturn(basemethod,currentmethod,**defaultcomparator) )
       
  2631                 {
       
  2632                     if (report)
       
  2633                     {
       
  2634 						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeReturn>(&basemethod, currentmethod,lineNo);
       
  2635                     }
       
  2636                     ++ret;
       
  2637                 }
       
  2638 
       
  2639                 if ( !CheckAccessModifier(basemethod,currentmethod) )
       
  2640                 {
       
  2641                     if (report)
       
  2642                     {
       
  2643 						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeAccess>(&basemethod, currentmethod,lineNo);
       
  2644                     }
       
  2645                     ++ret;
       
  2646                 }
       
  2647                 break;
       
  2648             }
       
  2649         }
       
  2650 
       
  2651         if ( cvirtualMethodsWithIndex.size() == ii )
       
  2652         {
       
  2653             //Method not found
       
  2654 
       
  2655 /*
       
  2656 			// This code detects if the removed virtual function was actually an removed override.
       
  2657             unsigned int baseindex = bvirtualMethodsWithIndex[i].second;
       
  2658             HANodeIterator basemethod(baseline);
       
  2659             basemethod.current = bvirtualMethodsWithIndex[i].first;
       
  2660 			
       
  2661 			if ( (baseindex < currentvtable.size()) && (currentvtable[baseindex].first == GenerateFunctionSignature(basemethod)) )
       
  2662 			{
       
  2663 				//This is a new override and we should report this if the class is derivable
       
  2664 				if (ClassIsDerivable(baseline))
       
  2665 				{
       
  2666 					if (report)
       
  2667 					{
       
  2668 						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeRemovedOverride>(&basemethod, basemethod);
       
  2669 					}
       
  2670 					++ret;
       
  2671 				}
       
  2672 			}
       
  2673 			else*/
       
  2674 			{				
       
  2675 				if (report)
       
  2676 				{
       
  2677 					AddIssue<EIssueIdentityVirtualFunction,EIssueTypeRemoval>(&basemethod, basemethod,parentLineNo);
       
  2678 				}
       
  2679 				++ret;
       
  2680 			}
       
  2681         }
       
  2682     }
       
  2683 
       
  2684     for (i = 0; i < virtualMethodFound.size(); ++i)
       
  2685     {
       
  2686         if (!virtualMethodFound[i])
       
  2687         {
       
  2688             HANodeIterator currentmethod(current);
       
  2689             currentmethod.current = cvirtualMethodsWithIndex[i].first;
       
  2690 
       
  2691 			lineNo = 0;
       
  2692 			const XMLCh* lineNumber = currentmethod.GetAttribute(KXMLLineString);
       
  2693 			lineNo = atoi(toString(lineNumber).c_str());
       
  2694 			//Check the base vtable for entry for this function
       
  2695             unsigned int baseindex = cvirtualMethodsWithIndex[i].second;
       
  2696 			
       
  2697 			if ( (baseindex < basevtable.size()) && (basevtable[baseindex].first == GenerateFunctionSignature(currentmethod)) )
       
  2698 			{
       
  2699 				//This is a new overwrite and we should report this if the class is derivable
       
  2700 				if (ClassIsDerivable(baseline))
       
  2701 				{
       
  2702 					if (report)
       
  2703 					{
       
  2704 						AddIssue<EIssueIdentityVirtualFunction,EIssueTypeNewOverride>(&currentmethod, currentmethod,lineNo);
       
  2705 					}
       
  2706 					++ret;
       
  2707 				}
       
  2708 			}
       
  2709 			else
       
  2710 			{	
       
  2711 				//This method really modifies the primary vtable
       
  2712 				// If you also want to find out if this function overrides entry in vtable of non-primary base 
       
  2713 				// then generate virtual table for them and search for the function signature from them
       
  2714 				if (report)
       
  2715 				{
       
  2716 					AddIssue<EIssueIdentityVirtualFunction,EIssueTypeAddition>(&currentmethod, currentmethod,lineNo);
       
  2717 				}
       
  2718 				++ret;
       
  2719 			}
       
  2720         }
       
  2721     }
       
  2722 	return ret;
       
  2723 }
       
  2724 
       
  2725 // ----------------------------------------------------------------------------
       
  2726 // ClassNodeAnalysis::compareBaseSizes
       
  2727 // ----------------------------------------------------------------------------
       
  2728 //
       
  2729 int ClassNodeAnalysis::compareBaseSizes(HANodeIterator baseline, HANodeIterator current, const NodeIndex::dtable_t& bfields, const NodeIndex::dtable_t& cfields, bool report)
       
  2730 {
       
  2731 	int ret = 0;
       
  2732 
       
  2733 	if ( ClassIsDerivable(baseline) )
       
  2734 	{
       
  2735 		int bbasesize = ClassBaseSize(baseline,bfields);
       
  2736 		int cbasesize = ClassBaseSize(current,cfields);
       
  2737 
       
  2738 		if ( (bbasesize) != (cbasesize) )
       
  2739 		{
       
  2740 			int lineNo = 0;
       
  2741 			const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  2742 			lineNo = atoi(toString(lineNumber).c_str());
       
  2743 			++ret;
       
  2744 			if (report)
       
  2745 			{		
       
  2746 				AddIssueClass<EIssueTypeBaseSize>(&baseline,iIdentity, current,lineNo);
       
  2747 			}
       
  2748 		}
       
  2749 	}
       
  2750 	return ret;
       
  2751 }
       
  2752 
       
  2753 // ----------------------------------------------------------------------------
       
  2754 // ClassNodeAnalysis::compareClassMembers
       
  2755 // ----------------------------------------------------------------------------
       
  2756 //
       
  2757 int ClassNodeAnalysis::compareClassMembers(HANodeIterator baseline,HANodeIterator current, bool report)
       
  2758 {
       
  2759 	int ret = 0;
       
  2760     //Base material
       
  2761     vector<DOMNode*> bvirtualMethods;
       
  2762     vector<DOMNode*> binlineMethods;
       
  2763     vector<DOMNode*> bexportedMethods;
       
  2764     vector<DOMNode*> bexportedvirtualMethods;
       
  2765     vector<DOMNode*> bmethods;
       
  2766     vector<DOMNode*> bfields;
       
  2767     vector<DOMNode*> bothers;
       
  2768 
       
  2769     //Current material
       
  2770     vector<DOMNode*> cvirtualMethods;
       
  2771     vector<DOMNode*> cinlineMethods;
       
  2772     vector<DOMNode*> cexportedMethods;
       
  2773     vector<DOMNode*> cexportedvirtualMethods;
       
  2774     vector<DOMNode*> cmethods;
       
  2775     vector<DOMNode*> cfields;
       
  2776     vector<DOMNode*> cothers;
       
  2777 
       
  2778     //Reserve some space for efficiency
       
  2779     bvirtualMethods.reserve(10);
       
  2780     bexportedMethods.reserve(10);
       
  2781     bmethods.reserve(10);
       
  2782     bfields.reserve(10);
       
  2783     bothers.reserve(10);
       
  2784 
       
  2785     cvirtualMethods.reserve(10);
       
  2786     cexportedMethods.reserve(10);
       
  2787     cmethods.reserve(10);
       
  2788     cfields.reserve(10);
       
  2789     cothers.reserve(10);
       
  2790 
       
  2791     //Order members
       
  2792     ClassOrderMembers(baseline,bvirtualMethods,binlineMethods,bexportedMethods,bexportedvirtualMethods,bmethods,bfields,bothers);
       
  2793     ClassOrderMembers(current,cvirtualMethods,cinlineMethods,cexportedMethods,cexportedvirtualMethods,cmethods,cfields,cothers);
       
  2794 
       
  2795 	//Virtual functions
       
  2796 	ret += compareVirtualFunctions(baseline, current, bvirtualMethods, cvirtualMethods, report);
       
  2797 
       
  2798 	//if ( baseline.CheckForBooleanAttribute(KXMLBBCVirtualString) )
       
  2799 	//{
       
  2800 		//ret += compareExportedVirtualFunctions(baseline, current, bexportedvirtualMethods, cexportedvirtualMethods, report);
       
  2801 	//}else if ( current.CheckForBooleanAttribute(KXMLBBCVirtualString) )
       
  2802 	//{
       
  2803 		//The class has changed from non-dynamic class to dynamic class
       
  2804 		//Do we need to report something?
       
  2805 	//}
       
  2806     
       
  2807     //Exported methods
       
  2808 	ret += compareNonvirtualFunctions(baseline,current,bexportedMethods,cexportedMethods,EIssueIdentityExportedFunction,report);
       
  2809 
       
  2810     //Inlined methods
       
  2811     ret += compareNonvirtualFunctions(baseline, current, binlineMethods, cinlineMethods,EIssueIdentityInlineFunction, report);
       
  2812 
       
  2813 	//Fields
       
  2814 	ret += compareFields(baseline,current,bfields, cfields, report);
       
  2815 
       
  2816 	//Others
       
  2817 	ret += compareOthers(baseline, current, bothers, cothers, report);
       
  2818 
       
  2819     return ret;
       
  2820 }
       
  2821 
       
  2822 // ----------------------------------------------------------------------------
       
  2823 // ClassNodeAnalysis::compareBases
       
  2824 // ----------------------------------------------------------------------------
       
  2825 //
       
  2826 int ClassNodeAnalysis::compareBases(HANodeIterator baseline,HANodeIterator current,bool report)
       
  2827 {
       
  2828     //Check base classes
       
  2829     int ret = 0;
       
  2830 
       
  2831     DOMNodeList* baselinechilds = baseline.GetElementsByTagName(KXMLBaseString);
       
  2832     DOMNodeList* currentchilds = current.GetElementsByTagName(KXMLBaseString);
       
  2833    
       
  2834     XMLSize_t baselinechildcount = baselinechilds->getLength();
       
  2835     XMLSize_t currentchildcount = currentchilds->getLength();
       
  2836 
       
  2837 	int lineNo = 0;
       
  2838 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  2839 	lineNo = atoi(toString(lineNumber).c_str());
       
  2840     if ( baselinechildcount == currentchildcount )
       
  2841     {
       
  2842 		unsigned int i = 0;
       
  2843         for (i = 0; i < baselinechildcount; ++i)
       
  2844         {
       
  2845             HANodeIterator baselineit(baseline);
       
  2846             HANodeIterator currentit(current);
       
  2847             baselineit.current = baselinechilds->item(i);
       
  2848             
       
  2849             HANodeIterator basenameit(baseline);
       
  2850             basenameit.FindNodeById(baselineit.GetAttribute(KXMLTypeString));
       
  2851             string basename( GenerateFullyQualifiedName(basenameit) );
       
  2852 
       
  2853 			unsigned int ii = 0;
       
  2854 			for (ii = 0; ii < currentchildcount; ++ii)
       
  2855 			{
       
  2856 				currentit.current = currentchilds->item(ii);
       
  2857 
       
  2858 				HANodeIterator currentnameit(current);
       
  2859 				currentnameit.FindNodeById(currentit.GetAttribute(KXMLTypeString));
       
  2860 				string currentname( GenerateFullyQualifiedName(currentnameit) );
       
  2861 				if ( basename == currentname )
       
  2862 				{
       
  2863 					if ( basenameit.CheckForBooleanAttribute(KXMLBBCVirtualString) )
       
  2864 					{
       
  2865 					
       
  2866 						const NodeIndex::vtable_t& basevtable = ClassGenerateVirtualTable(basenameit);
       
  2867 						const NodeIndex::vtable_t& currentvtable = ClassGenerateVirtualTable(currentnameit);
       
  2868 
       
  2869 						if ( 0 != compareVirtualTables(basenameit,currentnameit,basevtable,currentvtable,report) )
       
  2870 						{
       
  2871 							string vtablename = "[";
       
  2872 							vtablename += basename;
       
  2873 							vtablename += "-vtable]";
       
  2874 							AddIssue<EIssueIdentityVirtualTable,EIssueTypeChange>(&baseline, current, lineNo, NULL, vtablename);
       
  2875 						}
       
  2876 					
       
  2877 					}
       
  2878 					if ( 
       
  2879 						!Equals( baselineit.GetAttribute(KXMLVirtualString), currentit.GetAttribute(KXMLVirtualString)) )
       
  2880 					{
       
  2881 						//Virtuality differs
       
  2882 						if (report)
       
  2883 						{
       
  2884 							AddIssueClass<EIssueTypeInheritance>(&baseline,iIdentity, current,lineNo);
       
  2885 						}
       
  2886 						++ret;
       
  2887 					}
       
  2888             
       
  2889 					if ( !Equals( baselineit.GetAttribute(KXMLOffsetString), currentit.GetAttribute(KXMLOffsetString)) )
       
  2890 					{
       
  2891 						if (report)
       
  2892 						{
       
  2893 							string subobjectname = "[" + basename;
       
  2894 							subobjectname += "]";
       
  2895 							AddIssue<EIssueIdentitySubobject,EIssueTypeOffset>(&baseline,current,lineNo, NULL,subobjectname);
       
  2896 						}
       
  2897 						++ret;
       
  2898 					}
       
  2899 					break;
       
  2900 				}
       
  2901 			}
       
  2902 			if ( currentchildcount == ii )
       
  2903 			{
       
  2904 				if (report)
       
  2905 				{
       
  2906 					//AddIssueClass<EIssueTypeInheritance>(&baseline,iIdentity, current);
       
  2907                     //base class removed from inheritance
       
  2908 					string subobjectname = "[" + basename;
       
  2909 					subobjectname += "]";
       
  2910 					AddIssue<EIssueIdentitySubobject,EIssueTypeRemoval>(&baseline,current,lineNo, NULL,subobjectname);
       
  2911 				}
       
  2912 				++ret;
       
  2913 			}
       
  2914         }    
       
  2915     } else
       
  2916     {
       
  2917         //Different amount of bases
       
  2918         if (report)
       
  2919         {
       
  2920 			AddIssueClass<EIssueTypeInheritance>(&baseline,iIdentity, current,lineNo);
       
  2921         }
       
  2922         ++ret;
       
  2923 
       
  2924         //check if a base class is removed from inheritance
       
  2925 		unsigned int i = 0;
       
  2926         for (i = 0; i < baselinechildcount; ++i)
       
  2927         {
       
  2928             HANodeIterator baselineit(baseline);
       
  2929             HANodeIterator currentit(current);
       
  2930             baselineit.current = baselinechilds->item(i);
       
  2931             
       
  2932             HANodeIterator basenameit(baseline);
       
  2933             basenameit.FindNodeById(baselineit.GetAttribute(KXMLTypeString));
       
  2934             string basename( GenerateFullyQualifiedName(basenameit) );
       
  2935 
       
  2936 			unsigned int ii = 0;
       
  2937 			for (ii = 0; ii < currentchildcount; ++ii)
       
  2938 			{
       
  2939 				currentit.current = currentchilds->item(ii);
       
  2940 				
       
  2941 				HANodeIterator currentnameit(current);
       
  2942 				currentnameit.FindNodeById(currentit.GetAttribute(KXMLTypeString));
       
  2943 				
       
  2944 				string currentname( GenerateFullyQualifiedName(currentnameit) );
       
  2945 				if ( basename == currentname )
       
  2946 				{
       
  2947 					break;
       
  2948 				}
       
  2949 			}
       
  2950 			if ( currentchildcount == ii )
       
  2951 			{
       
  2952 				if (report)
       
  2953 				{
       
  2954 					string subobjectname = "[" + basename;
       
  2955 					subobjectname += "]";
       
  2956 					AddIssue<EIssueIdentitySubobject,EIssueTypeRemoval>(&baseline,current,lineNo, NULL,subobjectname);
       
  2957 				}
       
  2958 				++ret;
       
  2959 			}
       
  2960         }    
       
  2961     }
       
  2962 
       
  2963     return ret;
       
  2964 
       
  2965 }
       
  2966 
       
  2967 // ----------------------------------------------------------------------------
       
  2968 // ClassNodeAnalysis::ClassNodeAnalysis
       
  2969 // ----------------------------------------------------------------------------
       
  2970 //
       
  2971 ClassNodeAnalysis::ClassNodeAnalysis()
       
  2972     : iReportAddedMembers(false),
       
  2973       iIdentity(EIssueIdentityClass)
       
  2974 {
       
  2975 }
       
  2976 
       
  2977 
       
  2978 // ----------------------------------------------------------------------------
       
  2979 // ClassNodeAnalysis::Construct
       
  2980 // ----------------------------------------------------------------------------
       
  2981 //
       
  2982 NodeAnalysis* ClassNodeAnalysis::Construct()
       
  2983 {
       
  2984     return new ClassNodeAnalysis;
       
  2985 }
       
  2986 
       
  2987 // ----------------------------------------------------------------------------
       
  2988 // ClassNodeAnalysis::FindNodeAndAnalyse
       
  2989 // ----------------------------------------------------------------------------
       
  2990 //
       
  2991 int ClassNodeAnalysis::FindNodeAndAnalyse(HANodeIterator baseline,HANodeIterator current)
       
  2992 {
       
  2993     if ( baseline.CheckForBooleanAttribute(KXMIncompleteString) )
       
  2994     {
       
  2995         return 0;
       
  2996     }
       
  2997 
       
  2998      DOMNode* node = NodeAnalysis::findNode(baseline,current);
       
  2999     if ( !node )
       
  3000     {
       
  3001         //AddIssue<>(&baseline,EIssue_class_removal);
       
  3002         AddIssue<EIssueIdentityClass,EIssueTypeRemoval>(&baseline, baseline,0);
       
  3003         return 1;
       
  3004     }
       
  3005     current.current = node;
       
  3006 
       
  3007     return this->Analyse(baseline,current);
       
  3008 }
       
  3009 
       
  3010 // ----------------------------------------------------------------------------
       
  3011 // ClassNodeAnalysis::Analyse
       
  3012 // ----------------------------------------------------------------------------
       
  3013 //
       
  3014 int ClassNodeAnalysis::Analyse(HANodeIterator baseline,HANodeIterator current, bool report)
       
  3015 {
       
  3016     //ASSERTS
       
  3017     int ret=0;
       
  3018     short nodetype = baseline->getNodeType();    
       
  3019     assert(nodetype == DOMNode::ELEMENT_NODE);
       
  3020     nodetype = current->getNodeType();    
       
  3021     assert(nodetype == DOMNode::ELEMENT_NODE);
       
  3022 	int lineNo = 0;
       
  3023 	const XMLCh* lineNumber = current.GetAttribute(KXMLLineString);
       
  3024 	lineNo = atoi(toString(lineNumber).c_str());
       
  3025 
       
  3026     const XMLCh* baseanalysisstatus = baseline.GetAttribute(KXMLBBCAnalysisStatus);
       
  3027 
       
  3028     if (baseanalysisstatus)
       
  3029     {
       
  3030         if ( Equals(baseanalysisstatus,KXMLBBCAnalysisStatusAnalysing) )
       
  3031         {
       
  3032             //We are analysing recursively, should not happen
       
  3033             assert(false);
       
  3034         }
       
  3035         else if ( Equals(baseanalysisstatus,KXMLBBCAnalysisStatusClean) )
       
  3036         {
       
  3037             return 0;
       
  3038         }
       
  3039 
       
  3040 		if (!report)
       
  3041 		{
       
  3042 			return 1;
       
  3043 		}
       
  3044     }
       
  3045 
       
  3046     
       
  3047     baseline.SetAttribute(KXMLBBCAnalysisStatus,KXMLBBCAnalysisStatusAnalysing);
       
  3048 
       
  3049     bool bincomplete = baseline.CheckForBooleanAttribute(KXMIncompleteString);
       
  3050     bool cincomplete = current.CheckForBooleanAttribute(KXMIncompleteString);
       
  3051 
       
  3052     // Check if either baseline or current node is of incomplete type.
       
  3053     // Type is incomplete if the type is just forward declared or the
       
  3054     // analysed header file can be compiled without resolving the details
       
  3055     // of the type. This kind of situation occurs for example when only
       
  3056     // a reference or pointer to the class is used in the analyzed header, 
       
  3057     // and the class is declared in other header file.
       
  3058     //
       
  3059     // If the type is incomplete, we cannot compare the nodes.
       
  3060     if ( bincomplete || cincomplete )
       
  3061     {
       
  3062         if ( bincomplete && cincomplete )
       
  3063         {	
       
  3064             ret = 0;
       
  3065         }
       
  3066         else if (bincomplete)
       
  3067         {
       
  3068             ret = 0;
       
  3069         }
       
  3070         else
       
  3071         {            
       
  3072 			AddIssueClass<EIssueTypeNotAnalysed>(&baseline,iIdentity, baseline,0);
       
  3073             ret = 1;
       
  3074         }
       
  3075     }
       
  3076     else
       
  3077     {
       
  3078         // Check that the access level of the current node has not been changed
       
  3079         // to more restricted.
       
  3080         if (!CheckAccessModifier(baseline,current))
       
  3081         {
       
  3082             if (report)
       
  3083             {         
       
  3084 				AddIssueClass<EIssueTypeAccess>(&baseline,iIdentity, current,lineNo);
       
  3085             }
       
  3086             ret += 1;
       
  3087         }
       
  3088 
       
  3089 
       
  3090 		// Check if the class has virtual bases
       
  3091 		if ( baseline.CheckForBooleanAttribute(KXMLBBCVirtualInheritanceString) )
       
  3092 		{
       
  3093 			AddIssueClass<EIssueTypeVirtualBases>(&baseline,iIdentity, current,lineNo);
       
  3094 			++ret;
       
  3095 		}
       
  3096 
       
  3097 		if ( current.CheckForBooleanAttribute(KXMLBBCVirtualInheritanceString) )
       
  3098 		{
       
  3099 			AddIssueClass<EIssueTypeVirtualBases>(&current,iIdentity, current,lineNo);
       
  3100 			++ret;
       
  3101 		}
       
  3102 
       
  3103         // Check if the class is istantiable or derivable
       
  3104         if ( ClassIsInstantiable(baseline) || (ClassIsDerivable(baseline) && EIssueIdentityUnion != iIdentity) )
       
  3105         {
       
  3106 
       
  3107             if ( !CompareAttributes(baseline,current,KXMLAlignString,ESimpleAttribute) )
       
  3108             {
       
  3109                 if (report)
       
  3110                 {                    
       
  3111 					AddIssueClass<EIssueTypeAlign>(&baseline,iIdentity, current,lineNo);
       
  3112                     iReportAddedMembers = true;
       
  3113                 }
       
  3114                 ret += 1;
       
  3115             }
       
  3116 
       
  3117             if ( !CompareAttributes(baseline,current,KXMLSizeString,ESimpleAttribute) )
       
  3118             {
       
  3119                 if (report)
       
  3120                 {                 
       
  3121 					AddIssueClass<EIssueTypeSize>(&baseline,iIdentity, current,lineNo);
       
  3122                     iReportAddedMembers = true;
       
  3123                 }
       
  3124                 ret += 1;
       
  3125             }
       
  3126         }
       
  3127        	//ret += compareBaseSizes(baseline,current,report);
       
  3128         ret += compareClassMembers(baseline,current,report);
       
  3129         ret += compareBases(baseline,current,report);
       
  3130     }
       
  3131 
       
  3132     if ( ret == 0 )
       
  3133     {
       
  3134         baseline.SetAttribute(KXMLBBCAnalysisStatus,KXMLBBCAnalysisStatusClean);
       
  3135     } else
       
  3136     {
       
  3137         baseline.SetAttribute(KXMLBBCAnalysisStatus,KXMLBBCAnalysisStatusIssues);
       
  3138     }
       
  3139 
       
  3140     return ret;
       
  3141 }
       
  3142 
       
  3143 ////////////////////////////////////////////////////////////////////////////////////////
       
  3144 ///////////////////////////////StructNodeAnalysis///////////////////////////////////////
       
  3145 
       
  3146 // ----------------------------------------------------------------------------
       
  3147 // StructNodeAnalysis::Construct
       
  3148 // ----------------------------------------------------------------------------
       
  3149 //
       
  3150 NodeAnalysis* StructNodeAnalysis::Construct()
       
  3151 {
       
  3152     return new StructNodeAnalysis;
       
  3153 }
       
  3154 
       
  3155 // ----------------------------------------------------------------------------
       
  3156 // StructNodeAnalysis::StructNodeAnalysis
       
  3157 // ----------------------------------------------------------------------------
       
  3158 //
       
  3159 StructNodeAnalysis::StructNodeAnalysis()
       
  3160 {
       
  3161 	iIdentity = EIssueIdentityStruct;
       
  3162 }
       
  3163 ////////////////////////////////////////////////////////////////////////////////////////
       
  3164