private void fillOutStructureDef(HighVariable var) {
		Varnode startVN = var.getRepresentative();
		ArrayList<PointerRef> todoList = new ArrayList<>();
		HashSet<Varnode> doneList = new HashSet<>();

		todoList.add(new PointerRef(startVN, 0));	// Base Varnode on the todo list
		Varnode[] instances = var.getInstances();
		for (Varnode vn : instances) {
			doneList.add(vn);		// Mark instances as done to avoid recursion issues
			if (vn != startVN) {
				todoList.add(new PointerRef(vn, 0));	// Make sure all instances are on the todo list
			}
		}

		// while Todo list not empty
		while (!todoList.isEmpty()) {
			PointerRef currentRef = todoList.remove(0);
			if (currentRef.varnode == null) {
				continue;
			}

			Iterator<PcodeOp> descendants = currentRef.varnode.getDescendants();
			while (descendants.hasNext()) {
				PcodeOp pcodeOp = descendants.next();
				Varnode output = pcodeOp.getOutput();
				Varnode[] inputs = pcodeOp.getInputs();
				// println("off=" + offset + "     " + pcodeOp.getSeqnum().getTarget().toString() + " : "
				//		+ pcodeOp.toString());

				DataType outDt;
				long newOff;
				switch (pcodeOp.getOpcode()) {
					case PcodeOp.INT_SUB:
					case PcodeOp.INT_ADD:
						if (!inputs[1].isConstant()) {
							break;
						}
						long value = getSigned(inputs[1]);
						newOff = currentRef.offset +
							((pcodeOp.getOpcode() == PcodeOp.INT_ADD) ? value : (-value));
						if (sanityCheck(newOff, componentMap.getSize())) { // should this offset create a location in the structure?
							putOnList(output, newOff, todoList, doneList);
							// Don't do componentMap.addDataType() as data-type info here is likely uninformed
							componentMap.setMinimumSize(newOff);
						}
						break;
					case PcodeOp.PTRADD:
						if (!inputs[1].isConstant() || !inputs[2].isConstant()) {
							break;
						}
						newOff = currentRef.offset + getSigned(inputs[1]) * inputs[2].getOffset();
						if (sanityCheck(newOff, componentMap.getSize())) { // should this offset create a location in the structure?
							putOnList(output, newOff, todoList, doneList);
							// Don't do componentMap.addReference() as data-type info here is likely uninformed
							componentMap.setMinimumSize(newOff);
						}
						break;
					case PcodeOp.PTRSUB:
						if (!inputs[1].isConstant()) {
							break;
						}
						long subOff = currentRef.offset + getSigned(inputs[1]);
						if (sanityCheck(subOff, componentMap.getSize())) { // should this offset create a location in the structure?
							putOnList(output, subOff, todoList, doneList);
							// Don't do componentMap.addReference() as data-type info here is likely uninformed
							componentMap.setMinimumSize(subOff);
						}
						break;
					case PcodeOp.SEGMENTOP:
						// treat segment op as if it were a cast to complete the value
						//   The segment adds in some unknown base value.
						// get output and add to the Varnode Todo list
						putOnList(output, currentRef.offset, todoList, doneList);
						componentMap.setMinimumSize(currentRef.offset);
						break;
					case PcodeOp.LOAD:
						outDt = DecompilerUtils.getDataTypeTraceForward(output);
						componentMap.addDataType(currentRef.offset, outDt);

						if (outDt != null) {
							loadPcodeOps.add(new OffsetPcodeOpPair(currentRef.offset, pcodeOp));
						}

						break;
					case PcodeOp.STORE:
						// create a location in the struct
						//use the type of the varnode being put in to the structure
						if (pcodeOp.getSlot(currentRef.varnode) != 1) {
							break; // store must be into the target structure
						}
						outDt = DecompilerUtils.getDataTypeTraceBackward(inputs[2]);
						componentMap.addDataType(currentRef.offset, outDt);

						if (outDt != null) {
							storePcodeOps.add(new OffsetPcodeOpPair(currentRef.offset, pcodeOp));
						}

						break;
					case PcodeOp.CAST:
						putOnList(output, currentRef.offset, todoList, doneList);
						break;
					case PcodeOp.MULTIEQUAL:
						putOnList(output, currentRef.offset, todoList, doneList);
						break;
					case PcodeOp.COPY:
						putOnList(output, currentRef.offset, todoList, doneList);
						break;
					case PcodeOp.CALL:
						if (currentRef.offset == 0) {		// If pointer is passed directly (no offset)
							// find it as an input
							int slot = pcodeOp.getSlot(currentRef.varnode);
							if (slot > 0 && slot < pcodeOp.getNumInputs()) {
								Address storageAddr = computeParamAddress(inputs, slot);
								if (storageAddr != null) {
									addressToCallInputMap.put(inputs[0].getAddress(), storageAddr);
								}
							}
						}
						else {
							outDt = DecompilerUtils.getDataTypeTraceBackward(currentRef.varnode);
							componentMap.addReference(currentRef.offset, outDt);
						}
						break;
					case PcodeOp.CALLIND:
						outDt = DecompilerUtils.getDataTypeTraceBackward(currentRef.varnode);
						componentMap.addReference(currentRef.offset, outDt);
						break;
				}

			}
		}
	}
Look for Varnode references that are equal to the given variable plus a
constant offset and store them in the componentMap. The search is performed
by following data-flow paths starting at the given variable. If the variable flows
into a CALL instruction, put it in the addressToCallInputMap if offset is 0.
@param var is the given variable
Ghidra/Features/Decompiler/src/main/java/ghidra/app/decompiler/util/FillOutStructureHelper.java