WebKitTools/Scripts/detect-mismatched-virtual-const
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     1 #!/usr/bin/perl -w
       
     2 
       
     3 # Copyright (C) 2008 Apple Inc.  All rights reserved.
       
     4 #
       
     5 # Redistribution and use in source and binary forms, with or without
       
     6 # modification, are permitted provided that the following conditions
       
     7 # are met:
       
     8 #
       
     9 # 1.  Redistributions of source code must retain the above copyright
       
    10 #     notice, this list of conditions and the following disclaimer. 
       
    11 # 2.  Redistributions in binary form must reproduce the above copyright
       
    12 #     notice, this list of conditions and the following disclaimer in the
       
    13 #     documentation and/or other materials provided with the distribution. 
       
    14 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    15 #     its contributors may be used to endorse or promote products derived
       
    16 #     from this software without specific prior written permission. 
       
    17 #
       
    18 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    19 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    20 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    21 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    22 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    23 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    24 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    25 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    27 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    28 
       
    29 #
       
    30 # This script attempts to find instances of a problem where the signatures
       
    31 # of virtual methods fail to match because one is defined 'const', and another
       
    32 # is not. For example:
       
    33 #       virtual void Base::doStuff() const;
       
    34 #       virtual void Derived::doStuff();
       
    35 #
       
    36 # The lack of 'const' on the derived class gives it a different signature, and
       
    37 # it will therefore not be called when doStuff() is called on a derived object
       
    38 # via a base class pointer.
       
    39 #
       
    40 # Limitations of this script:
       
    41 # * It only works on things in the WebCore namespace
       
    42 # * Not all templatized methods may be found correctly
       
    43 # * It doesn't know anything about inheritance, or if methods are actually virtual
       
    44 # * It has lots of false positives (should add a whitelist for known-good signatures,
       
    45 #    and specific methods)
       
    46 # * It's rather slow
       
    47 #
       
    48 # Added by Simon Fraser <simon.fraser@apple.com>
       
    49 #
       
    50 # Run the script like this:
       
    51 #  WebKitTools/Scripts/detect-mismatched-virtual-const WebKitBuild/Debug/WebCore.framework/WebCore
       
    52 #
       
    53 # Output consists of a series of warnings like this:
       
    54 #
       
    55 # Both const and non-const versions of bgColor():
       
    56 #     HTMLDocument::bgColor()
       
    57 #     HTMLBodyElement::bgColor() const
       
    58 #     HTMLTableElement::bgColor() const
       
    59 #     HTMLTableRowElement::bgColor() const
       
    60 #     HTMLTableCellElement::bgColor() const
       
    61 #
       
    62 
       
    63 use strict;
       
    64 no warnings qw /syntax/;
       
    65 
       
    66 
       
    67 my $file = $ARGV[0];
       
    68 
       
    69 print "Looking for unmatched const methods in $file\n";
       
    70 
       
    71 if (!open NM, "(nm '$file' | c++filt | sed 's/^/STDOUT:/') 2>&1 |") {
       
    72     die "Could not open $file\n";
       
    73 }
       
    74 
       
    75 my $nestedParens;
       
    76    $nestedParens = qr /
       
    77                       [(]
       
    78                       [^()]*
       
    79                         (?:
       
    80                           (??{ $nestedParens })
       
    81                           [^()]*
       
    82                         )*
       
    83                       [)]/x;
       
    84 
       
    85 my $nestedAngleBrackets;
       
    86    $nestedAngleBrackets = qr /
       
    87                       [<]
       
    88                       [^<>]*
       
    89                         (?:
       
    90                           (??{ $nestedAngleBrackets })
       
    91                           [^<>]*
       
    92                         )*
       
    93                       [>]/x;
       
    94 
       
    95 my $bal;
       
    96    $bal = qr /([^:]+
       
    97               (??{ $nestedAngleBrackets })?
       
    98               (??{ $nestedParens }))
       
    99               ([^()]*)$/x;
       
   100 
       
   101 my %signature_map = ();
       
   102 
       
   103 while (<NM>) {
       
   104   my $line = $_;
       
   105   chomp($line);
       
   106   if ($line =~ m/ [tT] WebCore::(.+)$/) {
       
   107     my $method = $1;
       
   108     
       
   109     if ($method =~ /$bal/) {
       
   110       my $signature = $1;
       
   111       my $const = $2 eq " const";
       
   112       
       
   113       my $class = substr($method, 0, length($method) - length($signature) - ($const ? 6 : 0));
       
   114 
       
   115 #      print "line: $line\nclass: $class\nmethod: $method\nsignature: $signature\nconst: $const\n\n";
       
   116 
       
   117       my %method_info = (
       
   118           'class' => $class,
       
   119           'const' => $const,
       
   120           'method' => $method,
       
   121       );
       
   122       
       
   123       push @{$signature_map{$signature}}, \%method_info;
       
   124     } else {
       
   125       print "unmatched line $method\n\n"
       
   126     }
       
   127   }
       
   128 }
       
   129 close NM;
       
   130 
       
   131 my $sig;
       
   132 for $sig (keys %signature_map) {
       
   133   #print "\n$sig\n";
       
   134 
       
   135   my @entries = @{$signature_map{$sig}};
       
   136 #  print "$#entries\n";
       
   137   
       
   138   my $num_const = 0;
       
   139   my $num_not_const = 0;
       
   140   my $i;
       
   141   for $i (0 .. $#entries) {
       
   142     my $entry = @entries[$i];
       
   143 
       
   144     my $class = $entry->{'class'};
       
   145     my $const = $entry->{'const'};
       
   146     
       
   147     if ($const) {
       
   148       $num_const++;
       
   149     } else {
       
   150       $num_not_const++;
       
   151     }
       
   152   }
       
   153 
       
   154   if ($#entries > 1 && $num_const > 0 && $num_not_const > 0) {
       
   155     print "Both const and non-const versions of $sig:\n";
       
   156 
       
   157     for $i (0 .. $#entries) {
       
   158       my $entry = @entries[$i];
       
   159       my $method = $entry->{'method'};
       
   160       print "\t$method\n";
       
   161     }
       
   162 
       
   163   }
       
   164 }
       
   165 
       
   166 
       
   167