@Override
	public void setCustomVariableStorage(boolean hasCustomVariableStorage) {
		manager.lock.acquire();
		try {
			startUpdate();
			checkDeleted();
			if (thunkedFunction != null) {
				thunkedFunction.setCustomVariableStorage(hasCustomVariableStorage);
				return;
			}
			if (hasCustomVariableStorage == hasCustomVariableStorage()) {
				return;
			}
			loadVariables();

			if (!hasCustomVariableStorage) {
				// remove explicit 'this' param and return storage use if switching to dynamic storage
				removeExplicitThisParameter();
				DataType returnDt = removeExplicitReturnStoragePtrParameter();
				if (returnDt != null) {
					revertIndirectParameter(returnParam, returnDt, false);
				}
			}

			// get params and return prior to change
			Parameter[] parameters = getParameters();

			// remove auto-parameters
			autoParams = null;

			setFunctionFlag(FunctionAdapter.FUNCTION_CUSTOM_PARAM_STORAGE_FLAG,
				hasCustomVariableStorage);

			int ordinal = 0;
			for (Parameter p : parameters) {
				if (p.isAutoParameter()) {
					// must insert auto-params when switching to custom storage
					try {
						insertParameter(ordinal, new ParameterImpl(p, program),
							SourceType.ANALYSIS);
						++ordinal;
					}
					catch (DuplicateNameException e) {
						// skip - we don't want to rename auto-param
					}
				}
				else {
					// if not an auto-param p is a ParameterDB object
					// commit parameter storage and forced-indirect pointer when switching to custom
					// or switch to UNASSIGNED_STORAGE when switching to dynamic
					VariableStorage storage =
						hasCustomVariableStorage ? p.getVariableStorage().clone(program)
								: VariableStorage.UNASSIGNED_STORAGE;
					((ParameterDB) p).setStorageAndDataType(storage, p.getDataType());
				}
			}

			// commit return storage and forced-indirect pointer when switching to custom
			// or switch to UNASSIGNED_STORAGE when switching to dynamic
			VariableStorage storage =
				hasCustomVariableStorage ? returnParam.getVariableStorage().clone(program)
						: VariableStorage.UNASSIGNED_STORAGE;
			returnParam.setStorageAndDataType(storage, returnParam.getDataType());

			if (!hasCustomVariableStorage) {
				updateParametersAndReturn(); // assign dynamic storage
			}

			manager.functionChanged(this, PARAMETERS_CHANGED);
		}
		catch (InvalidInputException e) {
			throw new AssertException(e); // should not occur
		}
		finally {
			endUpdate();
			manager.lock.release();
		}
	}
Strip indirect pointer data type from a parameter.
@param param parameter to be examined and optionally modified
@param dt return datatype to be applied
@param create if true the specified param will not be affected and a new parameter
instance will be returned if strip performed, otherwise orginal param will be changed
if possible and returned.
@return parameter with pointer stripped or original param if pointer not used.
Returned parameter will have unassigned storage if affected.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/database/function/FunctionDB.java