private DecompilerVariable getMatchingVarialbe(DataType dt, DecompilerVariable var,
			DecompilerVariable potentialField) {

		String indent = "\t\t\t";

		DtrfDbg.println(this, indent + "Checking for matching variable; any casts?");
		List<DecompilerVariable> castVariables = var.getCasts();
		for (DecompilerVariable cast : castVariables) {
			if (matchesType(cast, dt)) {
				DtrfDbg.println(this, indent + "MATCHED cast: " + cast);
				return cast;
			}
		}

		String dtString = dt == null ? "null" : dt.toString();
		DtrfDbg.println(this,
			indent + "No matched casts; checking type against var:\n" +
				StringUtilities.indentLines("type: " + dtString, indent + "\t") + "\n" +
				StringUtilities.indentLines("var: " + var.toString(), indent + "\t"));
		if (matchesType(var, dt)) {
			DtrfDbg.println(this, indent + "MATCHED type: ");
			return var;
		}

		DtrfDbg.println(this, indent + "Type did not match; checking High Variable: ");

		//
		// 						Unusual Code Alert!
		// It is a bit odd to check the field when you are looking for the type that contains the
		// field.  BUT, in the Decompiler, SOMETIMES the 'field' happens to have the data type of
		// the thing that contains it.  So, if you have:
		// 		foo.bar
		// then the 'bar' field will have a data type of Foo.   Unfortunately, this is not always
		// the case.  For now, if there is a high variable, we need to check the field. Sad face
		// emoji.
		//
		HighVariable highVariable = var.variable.getHighVariable();
		if (highVariable != null) {
			if (matchesParentType(potentialField, dt)) {
				DtrfDbg.println(this, indent + "MATCHED on parent type: " + dt);
				return potentialField;
			}
		}

		DtrfDbg.println(this, indent + "NOT MATCHED");
		return null;
	}
A class that describes Decompiler variables and the fields that they may access.
Ghidra/Features/DecompilerDependent/src/main/java/ghidra/app/extension/datatype/finder/VariableAccessDR.java