# Virtual function not declared explicitly with the virtual keyword. use base ("Understand::Codecheck"); use strict; use constant ERR1 => "Missing Virtual Keyword"; sub register_tr_text { my $check = shift; $check->add_tr_text(ERR1); } sub name { return "10-3-2 Each overriding virtual function shall be declared with the virtual keyword."; } sub description { return "10-3-2 (Required) Each overriding virtual function shall be declared with the virtual keyword."; } sub detailed_description { return <<"END_DEF"

Rationale
Declaring overriding virtual functions with the virtual keyword removes the need to check the base class to determine whether a function is virtual.

Example
  class A 
  { 
  public: 
     virtual void g(); 
     virtual void b(); 
  };
  class B1 : public A 
  { 
  public: 
     virtual void g();  // Compliant     - explicitly declared "virtual" 
     void b();          // Non-compliant - implicitly virtual 
  };
END_DEF } sub test_language { my $language = shift; return $language =~ /C\+\+/; } sub test_entity { return 1; } sub test_global { return 0; } sub check { my $check = shift; my $file = shift; return unless $file->kind->check("file ~unresolved ~unknown"); my $lexer = $file->lexer(); return unless $lexer; foreach my $ref ($file->filerefs("define,declare","function virtual",1)) { my $func = $ref->ent(); # ignore func defs outside of the class body next if $ref->kind->check("define") && $func->ref("declarein"); do_one_ref($check,$lexer,$ref); } } sub do_one_ref { my ($check,$lexer,$ref) = @_; my $lexeme = $lexer->lexeme($ref->line(),$ref->column()) or return; # walk lexemes backwards until we find 'virtual' or hit something # that indicates we've gone too far. while ($lexeme) { my $text = $lexeme->text(); return if $text eq "virtual"; if ($text =~ m/[;{}]/){ $check->violation($ref->ent,$ref->file,$ref->line,$ref->column,ERR1); return; } $lexeme = $lexeme->previous(); } }