private void regenerateMultireturnStruct(Structure newStruct, DataTypeManager dtm,
			GoParamStorageAllocator storageAllocator) {

		String name = getComponentsInOriginalOrder(newStruct).stream()
				.map(dtc -> dtc.getDataType().getName())
				.collect(Collectors.joining(";", SHORT_MULTIVALUE_RETURNTYPE_PREFIX,
					SHORT_MULTIVALUE_RETURNTYPE_SUFFIX));

		if (newStruct.getName().equals(TMP_NAME)) {
			try {
				newStruct.setName(name);
			}
			catch (InvalidNameException | DuplicateNameException e) {
				// should not happen
			}
		}

		if (storageAllocator == null) {
			this.struct = newStruct;
			for (DataTypeComponent dtc : getComponentsInOriginalOrder(newStruct)) {
				stackStorageComponents.add(dtc);
			}
			return;
		}


		Structure adjustedStruct = new StructureDataType(newStruct.getCategoryPath(),
			name + "_" + storageAllocator.getArchDescription(), 0, dtm);
		adjustedStruct.setPackingEnabled(true);
		adjustedStruct.setExplicitPackingValue(1);

		storageAllocator = storageAllocator.clone();
		List<StackComponentInfo> stackResults = new ArrayList<>();
		int compNum = 0;
		for (DataTypeComponent dtc : getComponentsInOriginalOrder(newStruct)) {
			List<Register> regs = storageAllocator.getRegistersFor(dtc.getDataType());
			if (regs == null || regs.isEmpty()) {
				long stackOffset = storageAllocator.getStackAllocation(dtc.getDataType());
				String comment = "stack[%d] %s%d".formatted(stackOffset, ORDINAL_PREFIX, compNum);
				stackResults.add(new StackComponentInfo(dtc, compNum, comment));
			}
			else {
				String comment = "%s %s%d".formatted(regs, ORDINAL_PREFIX, compNum);
				DataTypeComponent newDTC =
					adjustedStruct.add(dtc.getDataType(), dtc.getFieldName(), comment);
				normalStorageComponents.add(newDTC);
			}
			compNum++;
		}

		// add the stack items to the struct first (LE) or last (BE), depending on endianness
		for (int i = 0; i < stackResults.size(); i++) {
			StackComponentInfo sci = stackResults.get(i);
			DataTypeComponent dtc = sci.dtc;
			DataTypeComponent newDTC = storageAllocator.isBigEndian()
					? adjustedStruct.add(dtc.getDataType(), dtc.getFieldName(), sci.comment)
					: adjustedStruct.insert(i, dtc.getDataType(), -1, dtc.getFieldName(),
						sci.comment);
			stackStorageComponents.add(newDTC);
		}

		boolean isEquiv = DWARFDataTypeConflictHandler.INSTANCE.resolveConflict(adjustedStruct,
			newStruct) == ConflictResult.USE_EXISTING;
		this.struct = isEquiv ? newStruct : adjustedStruct;
	}
Handles creating a Ghidra structure to represent multiple return values returned from a golang
function.
<p>
Assigning custom storage for the return value is complicated by:
<ul>
 <li>golang storage allocations depend on the formal ordering of the return values</li>
	<li>stack storage must be last in a list of varnodes</li>
	<li>the decompiler maps a structure's contents to the list of varnodes in an endian-dependent
	manner.</li>
</ul>
To meet these complications, the structure's layout is modified to put all items that were
marked as being stack parameters to either the front or back of the structure.
<p>
To allow this artificial structure to adjusted by the user and reused at some later time
to re-calculate the correct storage, the items in the structure are tagged with the original
ordinal of that item as a text comment of each structure field, so that the correct ordering
of items can be re-created when needed.
<p>
If the structure layout is modified to conform to an arch's requirements, the structure's
name will be modified to include that arch's description at the end (eg. "_x86_64")
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/golang/GoFunctionMultiReturn.java