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

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

			for (Function inlineFunction : inlineFunctionsList) {
				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, inlineFunction);
				List<Address> referencesToFunctions =
					extendedFlatAPI.getReferencesToFunctions(referenceToClassMap);

				// if some of the references are to functions figure out if they are
				// constructors destructors or add them to list of indetermined
				boolean isConstructor = false;
				boolean isDestructor = false;
				List<Address> referenceToIndeterminates = new ArrayList<Address>();

				if (!referencesToFunctions.isEmpty()) {
					for (Address functionReference : referencesToFunctions) {

						monitor.checkCancelled();
						Function function =
							extendedFlatAPI.getReferencedFunction(functionReference, true);

						if (function == null) {
							continue;
						}

						if (getAllConstructors().contains(function) ||
							getAllInlinedConstructors().contains(function)) {
							isConstructor = true;
							continue;
						}

						if (getAllDestructors().contains(function) ||
							getAllInlinedDestructors().contains(function)) {
							isDestructor = true;
							continue;
						}

						// TODO: refactor to make this function and refactor method that uses
						// it to use function instead of refiguring it out
						referenceToIndeterminates.add(functionReference);

					}

				}

				// if one or more is a constructor and none are destructors then the indeterminate
				// inline is an inlined constructor
				if (isConstructor == true && isDestructor == false) {
					processInlineConstructor(recoveredClass, inlineFunction, referenceToClassMap);
				}
				// if one or more is a destructor and none are constructors then the indeterminate
				// inline is an inlined destructor
				else if (isConstructor == false && isDestructor == true) {
					processInlineDestructor(recoveredClass, inlineFunction, referenceToClassMap);
				}
				else {

					// otherwise, use pcode info to figure out if inlined constructor or destructor
					//If not already, make function a this call
					makeFunctionThiscall(inlineFunction);

					List<OffsetPcodeOpPair> loads = getLoadPcodeOpPairs(inlineFunction);
					List<OffsetPcodeOpPair> stores = getStorePcodeOpPairs(inlineFunction);

					if (loads == null || stores == null) {
						Address firstVftableReferenceInFunction =
							getFirstVftableReferenceInFunction(inlineFunction);
						if (firstVftableReferenceInFunction == null) {
							continue;
						}

						FillOutStructureHelper fillStructHelper = runFillOutStructureHelper(
							inlineFunction, firstVftableReferenceInFunction);
						if (fillStructHelper == null) {
							continue;
						}

						loads = fillStructHelper.getLoadPcodeOps();
						loads = removePcodeOpsNotInFunction(inlineFunction, loads);
						stores = fillStructHelper.getStorePcodeOps();
						stores = removePcodeOpsNotInFunction(inlineFunction, stores);

						updateFunctionToStorePcodeOpsMap(inlineFunction, stores);
						updateFunctionToLoadPcodeOpsMap(inlineFunction, loads);

					}

					if (loads == null || stores == null) {
						continue;
					}

					// inlined constructor
					if (stores.size() > 1 && loads.size() == 0) {
						processInlineConstructor(recoveredClass, inlineFunction,
							referenceToClassMap);
						isConstructor = true;
					}

					// inlined destructor
					else if (stores.size() == 1 && loads.size() > 0) {
						processInlineDestructor(recoveredClass, inlineFunction,
							referenceToClassMap);
						isDestructor = true;
					}
				}

				if (!referenceToIndeterminates.isEmpty()) {
					// make the other referenced indeterminate c/d functions constructors
					if (isConstructor == true && isDestructor == false) {
						createListedConstructorFunctions(referenceToClassMap,
							referenceToIndeterminates);
						continue;
					}
					// make the other referenced indeterminate c/d functions destructors
					if (isConstructor == false && isDestructor == true) {
						createListedDestructorFunctions(referenceToClassMap,
							referenceToIndeterminates);
						continue;
					}

				}

			}

		}
	}
Method to figure out the indetermined inlined functions from each class as either combination
constructor/inlined constructor or destrucor/inlined destructor. The method first uses any
known called constructors or destructors to help determine which type then calls a method to
determine, using vftable order, which class contains the constructor/destructor and which
contains the inlined constructor/destructor.
@param recoveredClasses List of classes
@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
@throws CancelledException when cancelled and others
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RecoveredClassHelper.java