.NAME Definition of virtual function

.DESCRIPTION
	There shall be no more than one definition of each 
virtual function on each path through the inheritance hierarchy. 

.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 hasBody [expr [llength [::Semantic::getAttribute $curFunc sub]] > 0]
				set funcClass [::Semantic::getAttribute $curFunc class]
				set funcClassName [::Semantic::getAttribute $funcClass name]
				set funcClassAncestors [::Semantic::getAttribute $funcClass ancestors]
				set isPureVirtual 0
				if { [::Semantic::exists $curFunc isPureVirtual] } {
					set isPureVirtual 1
				}
				set isVirtual [expr [string equal virtual [::Semantic::getAttribute $curFunc qualifier]]]
				set allAncestorsVirtual 1
				set oneAncestorHasBody 0
				foreach curAncestor $funcClassAncestors {
					set curAccessor [lindex $curAncestor 0]
					set curClass [lindex $curAncestor 1]
					set curClassId [::Semantic::getAttribute $curClass name]
					set ancestorFunc [::Scopes::getWithName $curClass functions $funcName -1]
					if {[expr $ancestorFunc != -1]} {
						set ancestorFuncHasBody [expr [llength [::Semantic::getAttribute $ancestorFunc sub]] > 0]
						set oneAncestorHasBody [expr $oneAncestorHasBody || $ancestorFuncHasBody]

						set ancestorFuncName [::Semantic::getAttribute $ancestorFunc name]
						set isAncestorVirtual [::Semantic::exists $ancestorFunc isPureVirtual]
						set allAncestorsVirtual [expr $allAncestorsVirtual && $isAncestorVirtual]
					}
				}
				
				if {[expr [expr $isVirtual == 1] && [expr $isPureVirtual == 0] && [expr $hasBody == 1] && [expr $oneAncestorHasBody == 1]]} {
					::Semantic::violation $curFunc "MISRA_Rule10-3-1" "MISRA_Rule10-3-1 - There shall be no more than one definition of each virtual function on each path through the inheritance hierarchy."
				}
			}
		}
	}
}
