public void restoreXml(XmlPullParser parser, CompilerSpec cspec) throws XmlParseException {
		inputParams = null;
		outputParams = null;
		XmlElement protoElement = parser.start();
		name = protoElement.getAttribute(ATTRIB_NAME.name());
		if (!SpecExtension.isValidFormalName(name)) {
			throw new XmlParseException("Prototype name uses illegal characters");
		}
		extrapop = PrototypeModel.UNKNOWN_EXTRAPOP;
		String extpopStr = protoElement.getAttribute(ATTRIB_EXTRAPOP.name());
		if (!extpopStr.equals("unknown")) {
			extrapop = SpecXmlUtils.decodeInt(extpopStr);
		}
		stackshift = SpecXmlUtils.decodeInt(protoElement.getAttribute(ATTRIB_STACKSHIFT.name()));
		hasThis = false;
		isConstruct = false;
		String thisString = protoElement.getAttribute(ATTRIB_HASTHIS.name());
		if (thisString != null) {
			hasThis = SpecXmlUtils.decodeBoolean(thisString);
		}
		else {
			hasThis = name.equals(CompilerSpec.CALLING_CONVENTION_thiscall);
		}
		String constructString = protoElement.getAttribute(ATTRIB_CONSTRUCTOR.name());
		if (constructString != null) {
			isConstruct = SpecXmlUtils.decodeBoolean(constructString);
		}

		buildParamList(protoElement.getAttribute(ATTRIB_STRATEGY.name()));
		while (parser.peek().isStart()) {
			XmlElement subel = parser.peek();
			String elName = subel.getName();
			if (elName.equals(ELEM_INPUT.name())) {
				inputParams.restoreXml(parser, cspec);
			}
			else if (elName.equals(ELEM_OUTPUT.name())) {
				outputParams.restoreXml(parser, cspec);
			}
			else if (elName.equals(ELEM_PCODE.name())) {
				XmlElement el = parser.peek();
				String source = "Compiler spec=" + cspec.getCompilerSpecID().getIdAsString();
				if (el.getAttribute(ATTRIB_INJECT.name()).equals("uponentry")) {
					hasUponEntry = true;
				}
				else {
					hasUponReturn = true;
				}
				cspec.getPcodeInjectLibrary()
						.restoreXmlInject(source, getInjectName(), InjectPayload.CALLMECHANISM_TYPE,
							parser);
			}
			else if (elName.equals(ELEM_UNAFFECTED.name())) {
				unaffected = readVarnodes(parser, cspec);
			}
			else if (elName.equals(ELEM_KILLEDBYCALL.name())) {
				killedbycall = readVarnodes(parser, cspec);
			}
			else if (elName.equals(ELEM_RETURNADDRESS.name())) {
				returnaddress = readVarnodes(parser, cspec);
			}
			else if (elName.equals(ELEM_LIKELYTRASH.name())) {
				likelytrash = readVarnodes(parser, cspec);
			}
			else if (elName.equals(ELEM_INTERNAL_STORAGE.name())) {
				internalstorage = readVarnodes(parser, cspec);
			}
			else if (elName.equals(ELEM_LOCALRANGE.name())) {
				localRange = readAddressSet(parser, cspec);
			}
			else if (elName.equals(ELEM_PARAMRANGE.name())) {
				paramRange = readAddressSet(parser, cspec);
			}
			else {
				subel = parser.start();
				parser.discardSubTree(subel);
			}
		}
		parser.end(protoElement);
	}
Restore the model from an XML stream.
@param parser is the XML parser (initialized to the start of the stream)
@param cspec is the parent compiler specification owning the model
@throws XmlParseException is there are problems parsing the XML
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/lang/PrototypeModel.java