private void processDataTypes(RecoveredClass recoveredClass)
			throws CancelledException, Exception {

		// if recovered class is a special typeinfo class skip it
		if (recoveredClass.getName().endsWith("_class_type_info")) {
			Msg.debug(this,
				"Not creating class data type for " +
					recoveredClass.getClassNamespace().getName(true) +
					" because it is one of the special typeinfo classes.");
			return;
		}

		// can't handle creating class data types for classes with virtual parents yet
		if (recoveredClass.inheritsVirtualAncestor()) {
			Msg.debug(this,
				"Cannot create class data type for " +
					recoveredClass.getClassNamespace().getName(true) +
					" because it has virtual ancestors and we don't yet handle that use case.");
			return;
		}

		// skip any classes that have special typeinfo class parents
		if (recoveredClass.hasParentClass()) {
			List<RecoveredClass> parentList = recoveredClass.getParentList();
			for (RecoveredClass parent : parentList) {
				monitor.checkCancelled();
				if (parent.getName().endsWith("_class_type_info")) {
					Msg.debug(this, "Not creating class data type for " +
						recoveredClass.getClassNamespace().getName(true) +
						" because it has a parent that is one of the special typeinfo classes.");
					return;
				}
			}
		}

		// can't handle creating class data types for diamond shaped classes yet
		if (recoveredClass.isDiamondShaped()) {
			Msg.debug(this,
				"Cannot create class data type for " +
					recoveredClass.getClassNamespace().getName(true) +
					" because it is diamond shaped and we don't yet handle that use case.");
			return;
		}

		if (!recoveredClass.hasVftable()) {

			Structure classStructure = createSimpleClassStructure(recoveredClass, null);
			if (classStructure == null) {
				Msg.error(this, "Could not create class structure for " +
					recoveredClass.getClassNamespace().getName(true));
			}

			updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStructure);
			// return in this case because if there is no vftable for a class the script cannot
			// identify any member functions so there is no need to process the rest of this
			// method
			return;
		}

		// create pointers to empty vftable structs so they can be added to the class
		// data type
		// then filled in later
		Map<Address, DataType> vfPointerDataTypes = createEmptyVfTableStructs(recoveredClass);

		// create current class structure and add pointer to vftable, all parent member
		// data
		// structures, and class member data structure
		Structure classStruct = createSimpleClassStructure(recoveredClass, vfPointerDataTypes);
		if (classStruct == null) {
			Msg.error(this, "Could not create class structure or continue processing for " +
				recoveredClass.getClassNamespace().getName(true));
			return;
		}

		// Now that we have a class data type
		// name constructor and destructor functions and put into the class namespace
		addConstructorsToClassNamespace(recoveredClass, classStruct);
		addDestructorsToClassNamespace(recoveredClass, classStruct);
		// TODO:
//			addNonThisDestructorsToClassNamespace(recoveredClass);
//			addVbaseDestructorsToClassNamespace(recoveredClass);
//			addVbtableToClassNamespace(recoveredClass);
		// TODO:
//			// add secondary label on functions with inlined constructors or destructors
//			createInlinedConstructorComments(recoveredClass);
//			createInlinedDestructorComments(recoveredClass);
//			createIndeterminateInlineComments(recoveredClass);

		// add label on constructor destructor functions that could not be determined
		createIndeterminateLabels(recoveredClass, classStruct);

		// This is done after the class structure is created and added to the dtmanager
		// because if done before the class structures are created
		// then empty classes will get auto-created in the wrong place
		// when the vfunctions are put in the class

		fillInAndApplyVftableStructAndNameVfunctions(recoveredClass, vfPointerDataTypes,
			classStruct);

		updateClassFunctionsNotUsingNewClassStructure(recoveredClass, classStruct);
	}
Method to create all the class data types for the current class, name all the
class functions, and put them all into the class namespace

@param recoveredClass current class
@throws CancelledException when cancelled
@throws Exception          naming exception
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java