private boolean processFunctionDef(XmlTreeNode root, boolean firstPass) {
		boolean processedAll = true;
		XmlElement element = root.getStartElement();
		String name = element.getAttribute("NAME");
		CategoryPath path = getCategoryPath(element);
		FunctionDefinition fd = null;

		if (firstPass) {
			fd = new FunctionDefinitionDataType(path, name);
			fd = (FunctionDefinition) dataManager.addDataType(fd, null);
			if (!name.equals(fd.getName())) {
				element.setAttribute("NAME", fd.getName());
			}
		}
		else {
			fd = (FunctionDefinition) dataManager.getDataType(path, name);
		}

		XmlTreeNode node = root.getChild("RETURN_TYPE");
		if (node != null) {
			DataType returnType = findDataType(node.getStartElement());
			if (returnType != null) {
				fd.setReturnType(returnType);
				root.deleteChildNode(node);
			}
			else {
				processedAll = false;
			}
		}

		Iterator<XmlTreeNode> it = root.getChildren("PARAMETER");
		while (it.hasNext()) {
			node = it.next();
			String comment = getRegularComment(node);
			element = node.getStartElement();
			DataType dt = findDataType(element);
			if (dt != null) {
				int ordinal = XmlUtilities.parseInt(element.getAttribute("ORDINAL"));
				name = element.getAttribute("NAME");
				int size = dt.getLength();
				if (size == 0) {
					return false;
				}
				if (size < 0) {
					size = element.hasAttribute("SIZE")
							? XmlUtilities.parseInt(element.getAttribute("SIZE"))
							: 4;
				}
				fd.replaceArgument(ordinal, name, dt, comment, SourceType.USER_DEFINED);
				it.remove();
			}
			else {
				processedAll = false;
			}
		}
		return processedAll;
	}
Reads the datatypes encoded in XML from the specified XML parser and recreates
them in a datatype manager.
@param parser the XML parser
@param monitor the task monitor
@throws SAXParseException if an XML parse error occurs
@throws CancelledException if the user cancels the read operation
Ghidra/Features/Base/src/main/java/ghidra/app/util/xml/DataTypesXmlMgr.java