public void findInlineConstructorsAndDestructorsUsingRelatedClassFunctions(
			List<RecoveredClass> recoveredClasses) throws CancelledException, InvalidInputException,
			DuplicateNameException, CircularDependencyException {

		for (RecoveredClass recoveredClass : recoveredClasses) {
			monitor.checkCancelled();
			List<Function> indeterminateList =
				new ArrayList<Function>(recoveredClass.getIndeterminateInlineList());

			if (indeterminateList.isEmpty()) {
				continue;
			}

			List<Function> allRelatedConstructors = getAllAncestorConstructors(recoveredClass);
			List<Function> allRelatedDestructors = getAncestorDestructors(recoveredClass);

			for (Function indeterminateFunction : indeterminateList) {
				monitor.checkCancelled();
				// get the addresses in the function that refer to classes either by
				// referencing a vftable in a class or by calling a function in a class
				Map<Address, RecoveredClass> referenceToClassMap =
					getReferenceToClassMap(recoveredClass, indeterminateFunction);

				List<Function> allDescendantConstructors =
					getAllDescendantConstructors(recoveredClass);
				if (allDescendantConstructors.contains(indeterminateFunction)) {
					processInlineConstructor(recoveredClass, indeterminateFunction,
						referenceToClassMap);
					continue;
				}

				List<Function> allDescendantDestructors =
					getAllDescendantDestructors(recoveredClass);
				if (allDescendantDestructors.contains(indeterminateFunction)) {
					processInlineDestructor(recoveredClass, indeterminateFunction,
						referenceToClassMap);
					continue;
				}

				List<Function> possibleAncestorConstructors =
					getPossibleParentConstructors(indeterminateFunction);

				Function ancestorConstructor =
					getFunctionOnBothLists(possibleAncestorConstructors, allRelatedConstructors);

				List<Function> possibleAncestorDestructors =
					getPossibleParentDestructors(indeterminateFunction);

				Function ancestorDestructor =
					getFunctionOnBothLists(possibleAncestorDestructors, allRelatedDestructors);

				// skip if both null - no results
				if (ancestorConstructor == null && ancestorDestructor == null) {
					continue;
				}

				// skip if both null - conflicting results
				if (ancestorConstructor != null && ancestorDestructor != null) {
					continue;
				}

				if (ancestorConstructor != null) {
					processInlineConstructor(recoveredClass, indeterminateFunction,
						referenceToClassMap);
					continue;
				}

				if (ancestorDestructor != null) {
					processInlineDestructor(recoveredClass, indeterminateFunction,
						referenceToClassMap);
					continue;
				}

			}
		}

	}
Method to classify indeterminate inline functions as either constructors or destructors
using called ancestor information (may call parent or higher ancestor) or might be the same
as a descendant constructor/destructor (ie a parent or ancestor is inlined into an
indeterminate function so the same function is on both the parent inline list and the
descendant regular list.
@param recoveredClasses list of classes
@throws CancelledException if cancelled
@throws CircularDependencyException if parent namespace is descendant of given namespace
@throws DuplicateNameException if try to create same symbol name already in namespace
@throws InvalidInputException if error setting return type
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java