private DWARFDataType makeDataTypeForFunctionDefinition(DIEAggregate diea)
			throws IOException, DWARFExpressionException {

		DWARFName dni = prog.getName(diea);

		// push an empty funcdef data type into the lookup cache to prevent recursive loops
		FunctionDefinitionDataType funcDef =
			new FunctionDefinitionDataType(dni.getParentCP(), dni.getName(), dataTypeManager);
		DataType dtToAdd = funcDef;

		int cuLang = diea.getCompilationUnit().getLanguage();
		if (cuLang == DWARFSourceLanguage.DW_LANG_Go) {
			if (diea.hasAttribute(DW_AT_byte_size)) {
				// if the funcdef has a bytesize attribute, we should convert this data type to a ptr
				long ptrSize = diea.getUnsignedLong(DW_AT_byte_size, -1);
				if (ptrSize == dataTypeManager.getDataOrganization().getPointerSize()) {
					ptrSize = -1;// use default pointer size
				}
				dtToAdd = dwarfDTM.getPtrTo(dtToAdd, (int) ptrSize);
			}
			//  golang funcdefs are ptr->ptr->funcs
			dtToAdd = dwarfDTM.getPtrTo(dtToAdd, -1);
		}

		DWARFDataType result = new DWARFDataType(dtToAdd, dni, diea.getOffset());
		recordTempDataType(result);  // prevents recursive type-lookups for this funcdef

		DWARFDataType returnType = getDataType(diea.getTypeRef(), voidDDT);

		boolean foundThisParam = false;
		List<ParameterDefinition> params = new ArrayList<>();
		for (DIEAggregate paramDIEA : diea.getFunctionParamList()) {

			String paramName = paramDIEA.getName();
			DWARFDataType paramDT = getDataType(paramDIEA.getTypeRef(), null);
			DataType dt = fixupDataTypeInconsistencies(paramDT);

			if (dt == null || dt.getLength() <= 0) {
				Msg.error(this, "Bad function parameter type for " + dni.asCategoryPath());
				return null;
			}

			ParameterDefinition pd = new ParameterDefinitionImpl(paramName, dt, null);
			params.add(pd);

			foundThisParam |= DWARFUtil.isThisParam(paramDIEA);
		}

		funcDef.setReturnType(returnType.dataType);
		funcDef.setNoReturn(diea.getBool(DW_AT_noreturn, false));
		funcDef.setArguments(params.toArray(new ParameterDefinition[params.size()]));

		if (!diea.getChildren(DW_TAG_unspecified_parameters).isEmpty()) {
			funcDef.setVarArgs(true);
		}

		if (foundThisParam) {
			try {
				funcDef.setCallingConvention(CompilerSpec.CALLING_CONVENTION_thiscall);
			}
			catch (InvalidInputException e) {
				Msg.error(this, "Unexpected calling convention error", e);
			}
		}

		if (dni.isAnon()) {
			String mangledName = DataTypeNamingUtil.setMangledAnonymousFunctionName(funcDef);
			dni = dni.replaceName(mangledName, dni.getOriginalName());
		}

		for (int i = 0; i < funcDef.getArguments().length; i++) {
			ParameterDefinition origPD = params.get(i);
			ParameterDefinition newPD = funcDef.getArguments()[i];
			updateMapping(origPD.getDataType(), newPD.getDataType());
		}

		return result;
	}
Returns true if the previously imported data type should be reused.
<p>
Don't re-use empty structs (isNotYetDefined) to ensure that newer
definitions of the same struct are given a chance to be resolved() 
into the DTM. 

@param alreadyImportedDT dataType to check
@return boolean true if its okay to reuse the data type
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf/DWARFDataTypeImporter.java