public static Data createData(Program program, Address addr, DataType newType, int length,
			boolean stackPointers, ClearDataMode clearMode) throws CodeUnitInsertionException {

		Listing listing = program.getListing();
		ReferenceManager refMgr = program.getReferenceManager();

		Data data = getData(addr, clearMode, listing);
		int existingLength = addr.getAddressSpace().getAddressableUnitSize();
		DataType existingType = data.getDataType();
		Reference extRef = null;
		if (!isParentData(data, addr)) {

			if (!stackPointers && isDataClearingDenied(existingType, clearMode)) {
				throw new CodeUnitInsertionException("Could not create Data at address " + addr);
			}

			existingLength = data.getLength();

			if (data.isDefined()) {
				DataType existingDt = data.getDataType();
				if (stackPointers && (newType instanceof Pointer) &&
					(existingDt instanceof Pointer ptr)) {
					if (isDefaultPointer(newType)) {
						// When applying default-pointer to existing pointer replicate the outermost
						// pointer type to wrap existing pointer (e.g., char* becomes char**)
						newType = ptr.newPointer(ptr);
					}
					// Any use of stacking already reflected by newType
					stackPointers = false;
				}
				if (newType.isEquivalent(existingType)) {
					return data;
				}
			}

			// TODO: This can probably be eliminated
			// Check for external reference on pointer
			extRef =
				getExternalPointerReference(addr, newType, stackPointers, refMgr, existingType);
		}

		newType = newType.clone(program.getDataTypeManager());
		newType = reconcileAppliedDataType(existingType, newType, stackPointers);

		DataType realType = newType;
		if (newType instanceof TypeDef) {
			realType = ((TypeDef) newType).getBaseDataType();
		}

		// is the datatype already there?
		if (isExistingNonDynamicType(realType, newType, existingType)) {
			return data;
		}

		DataTypeInstance dti = getDtInstance(program, addr, newType, length, realType);
		if (stackPointers && existingType instanceof Pointer && newType instanceof Pointer) {
			listing.clearCodeUnits(addr, addr, false);
		}

		Data newData;
		try {
			newData = listing.createData(addr, dti.getDataType(), dti.getLength());
		}
		catch (CodeUnitInsertionException e) {
			// ok lets see if we need to clear some code units
			if (clearMode == ClearDataMode.CLEAR_SINGLE_DATA) {
				listing.clearCodeUnits(addr, addr, false);
			}
			else {
				checkEnoughSpace(program, addr, existingLength, dti, clearMode);
			}
			newData = listing.createData(addr, dti.getDataType(), dti.getLength());
		}

		restoreReference(newType, refMgr, extRef);

		return newData;
	}
Create data where existing data may already exist.
@param program the program
@param addr data address (offcut data address only allowed if clearMode == ClearDataMode.CLEAR_ALL_CONFLICT_DATA)
@param newType new data-type being applied
@param length data length (used only for Dynamic newDataType which has canSpecifyLength()==true)
@param stackPointers see {@link #reconcileAppliedDataType(DataType, DataType, boolean)}
@param clearMode see CreateDataMode
@return new data created
@throws CodeUnitInsertionException if data creation failed
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/data/DataUtilities.java