private boolean analyzeFunction(Function f, TaskMonitor monitor) throws CancelledException {
		Address entry = f.getEntryPoint();

		// Perform depth search of all functions reached by this function.
		// Any function that has not had its stack analyzed is added to a list.
		// This way, the lowest level functions frames are looked at to try and determine their
		//  stack purge, before this functions stack is analyzed.
		Stack<Function> stack = new Stack<>(); // functions needing to be looked at for valid frames
		ArrayList<Function> funcList = new ArrayList<>(); // list of functions needing stack frames created
		stack.push(f);
		while (!stack.isEmpty()) {
			monitor.checkCancelled();
			Function func = stack.pop();
			if (func.isThunk()) {
				continue;
			}

			if (forceProcessing && func.getEntryPoint().equals(entry)) {
				// This function needs its stack looked at.
				funcList.add(0, func);
			}

			// If the function has no references to stack or local variables, compute them
			// Later this should change to stack locked.
			Variable[] variables = func.getVariables(VariableFilter.STACK_VARIABLE_FILTER);
			boolean hasReferences = false;
			for (Variable variable : variables) {
				Reference[] referencesTo = program.getReferenceManager().getReferencesTo(variable);
				if (referencesTo.length != 0) {
					hasReferences = true;
					break;
				}
			}
			if (variables.length == 0 || !hasReferences) {
				// TODO: SHOULD HAVE OPTION JUST TO CREATE REFERENCES
				// TODO: SHOULD HAVE OPTION JUST TO CREATE PARAMETERS
				// TODO: SHOULD HAVE OPTION JUST TO CREATE LOCALS
				funcList.add(0, func);
			}
		}

		// Process all the functions identified as needing stack analysis.
		// The list will have the lowest level functions analyzed first.
		while (!funcList.isEmpty()) {
			monitor.checkCancelled();
			Function func = funcList.remove(0);
			SourceType oldSignatureSource = func.getSignatureSource();

			monitor.setMessage("Stack " + func.getName());
			createStackPointerVariables(func, monitor);

			// Now check that there are not missing stack variables
			//addMissingStackVariables(func);

			if (oldSignatureSource != func.getSignatureSource()) {
				// preserve signature source 
				func.setSignatureSource(oldSignatureSource);
			}
		}
		return true;
	}
Analyze a function to build a stack frame based on stack references.

@param f   function to analyze
@param monitor the task monitor that is checked to see if the command has
been cancelled.
@throws CancelledException if the user canceled this command
Ghidra/Features/Base/src/main/java/ghidra/app/cmd/function/NewFunctionStackAnalysisCmd.java