.NAME Virtual function

.DESCRIPTION
	Each overriding virtual function shall be declared with the virtual keyword. 

.COMMENT V7.0

.SEVERITY Required

.COMMENT
Please refer to the MISRA C++:2008 document for further details (www.misra-cpp.com)

.REQUIRED cpp_semantic

.COMMAND tcl

.CODE

::logiscope::include -once common utilities.tcl

proc compute {standardName tree} {  
	if {[string equal [::logiscope::fileName] [::logiscope::firstFile]]} {
		checkFunctions
	}
}

proc checkFunctions {} {
	foreach curScope [::Scopes::getAllScopes] {
		foreach curFunc [::Semantic::getAttribute $curScope functions] {
			set funcName [::Semantic::getAttribute $curFunc name]
			if {[::Semantic::exists $curFunc class]} {
				set hasUpperFunc 1
				set funcClass [::Semantic::getAttribute $curFunc class]
				set funcClassAncestors [::Semantic::getAttribute $funcClass ancestors]
				set qualifier [::Semantic::getAttribute $curFunc qualifier]
				set virtual 0
				if { [lsearch $qualifier virtual] >= 0 } {
					set virtual 1
				}
				set nbAncestors [llength $funcClassAncestors]
				set allAncestorsVirtual 1
				foreach curAncestor $funcClassAncestors {
					set curClass [lindex $curAncestor 1]
					set ancestorFunc [::Scopes::getWithName $curClass functions $funcName -1]
					set hasUpperFunc 1
					if {[expr $ancestorFunc != -1]} {
						set hasUpperFunc [expr $hasUpperFunc && 1]
						set qualifier [::Semantic::getAttribute $ancestorFunc qualifier]
						set isAncestorVirtual 0
						if { [lsearch $qualifier virtual] >= 0 } {
							set isAncestorVirtual 1
						}
						set allAncestorsVirtual [expr $allAncestorsVirtual && $isAncestorVirtual]
					} else {
						set hasUpperFunc [expr $hasUpperFunc && 0]
					}
				}
				if {[expr [expr $virtual == 0] && [expr $nbAncestors > 0] && [expr $allAncestorsVirtual == 1] && [expr $hasUpperFunc == 1]]} {
					::Semantic::violation $curFunc "MISRA_Rule10-3-2" "MISRA_Rule10-3-2 - Each overriding virtual function shall be declared with the virtual keyword."
				}
			}
		}
	}
}

