CategoryPath getCategoryPathForFunctionSignature(Function vfunction, String functionDefName,
			RecoveredClass recoveredClass, Address vftableAddress)
			throws CancelledException, InvalidNameException {

		// if class has no parent, return its own classPath
		CategoryPath classPath = recoveredClass.getClassPath();
		if (!recoveredClass.hasParentClass()) {
			return classPath;
		}

		// if no ancestor has virtual functions then return the given class's class path
		List<RecoveredClass> ancestorsWithVirtualFunctions =
			getAncestorsWithVirtualFunctions(recoveredClass);
		if (ancestorsWithVirtualFunctions.size() == 0) {
			return classPath;
		}

		// if the class has multiple inheritance or single virtual inheritance get the parent from
		// the "_for_<parentName>" in the given vftable
		if (recoveredClass.hasMultipleInheritance() ||
			(recoveredClass.hasSingleInheritance() && recoveredClass.inheritsVirtualAncestor())) {
			RecoveredClass parentClass = recoveredClass.getVftableBaseClass(vftableAddress);

			// if can't recover the parent from the vftable just return the class's class path
			if (parentClass == null) {
				return classPath;
			}

			// else return the parent associated with the vftableAddress
			return parentClass.getClassPath();
		}

		// else class has normal single inheritance so just search for the matching function definition
		// in one of the class's ancestors and return the ancestor class it is found in or if not found,
		// return the current class
		List<RecoveredClass> classHierarchy = recoveredClass.getClassHierarchy();

		// classHierarchy list always contains current class in first item so skip that one
		// to search only the ancestors
		Iterator<RecoveredClass> classHierarchyIterator = classHierarchy.listIterator(1);

		// TODO: eventually use the function definition to do an equivalence check amongst
		// possible same-name vfunctions to make sure getting the correct one
		// in this case need to update the below check in dtMan to look through the .conflicts
//		FunctionDefinition functionDataType = new FunctionDefinitionDataType(vfunction, true);
//
//		functionDataType.setReturnType(vfunction.getReturnType());
//		try {
//			functionDataType.setName(functionDefName);
//		}
//		catch (DuplicateNameException e) {
//			// ignore -- don't rename if it is already the same name
//		}

		while (classHierarchyIterator.hasNext()) {
			monitor.checkCancelled();

			RecoveredClass currentClass = classHierarchyIterator.next();

			CategoryPath currentClassPath = currentClass.getClassPath();
			DataType existingDataType =
				dataTypeManager.getDataType(currentClassPath, functionDefName);

			if (existingDataType != null) {
				return currentClassPath;
			}

		}
		return classPath;

	}
Method to retrieve the class path of the highest ancestor with matching vfunction in its vftable
@param vfunction the given virtual function
@param functionDefName the given function definition name
@param recoveredClass the given class
@param vftableAddress the given virtual function table from the given class
@return the class path for the highest ancestor with matching virtual function in its vftable
@throws CancelledException when cancelled
@throws InvalidNameException if functionDefName is invalid name
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java