@Override
		public void decompile(Function func, TaskMonitor monitor) {
			if ((monitor != null) && (monitor.isCancelled())) {
				return;
			}
			if (func.isThunk()) {
				return;
			}
			Address entryPoint = func.getEntryPoint();
			if (!hasBody(entryPoint)) {
				return;
			}
			FunctionDescription fdesc =
				manager.containsDescription(func.getName(true), entryPoint.getOffset(), exerec);
			if (fdesc != null && fdesc.getSignatureRecord() != null) {	// Is signature for this function already present
				return;
			}
			SignatureResult sigres = decompiler.generateSignatures(func, gencallgraph,
				options.getDefaultTimeout(), monitor);

			if ((monitor != null) && (monitor.isCancelled())) {
				return;
			}

			if (sigres == null) {
				String errmsg = decompiler.getLastMessage();
				if ((errmsg != null) && !errmsg.isEmpty()) {
					//					throw new DecompileException("signature",errmsg);
					Msg.error(this, "Error generating signature for \"" + func.getName() +
						"\".  Error: " + errmsg);
				}
				return;
			}
			else if (sigres.features.length == 0) {
				Msg.error(this, "No features in signature for \"" + func.getName() + '\"');
				return;
			}
			int flags = recoverAttributes(func);
			if (sigres.hasunimplemented) {
				flags |= FunctionTagBSimFilterType.HAS_UNIMPLEMENTED_MASK;
			}
			if (sigres.hasbaddata) {
				flags |= FunctionTagBSimFilterType.HAS_BADDATA_MASK;
			}
			List<CallRecord> callrecs;
			if (gencallgraph) {
				callrecs = collectCallsFromAddress(sigres.calllist);
			}
			else {
				callrecs = new ArrayList<CallRecord>();
			}
			writeToManager(func, sigres.features, callrecs, flags);
		}
Info for resolving a call to a unique function in the database.
For normal functions you need the triple (executable, function name, address)
For calls to library (external) functions, only the library executable
and the function name are needed, and the address is filled in with -1
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/GenSignatures.java