public static MDDataType parseDataType(MDMang dmang, boolean isHighest) throws MDException {
		MDDataType dt;
		char code = dmang.peek();
		switch (code) {
			case '?':
				dmang.increment();
				dt = new MDQuestionModifierType(dmang);
				break;
			case 'X':
				// The wiki document says 'X' can be void or coclass, but we have never been able
				//  to make coclass manifest itself, so we are factoring out the code that could
				//  have allowed it: This was MDMang.xVoidPermitted(), which read a flag from
				//  MDContext.  The ability is also being factored out of MDContext.
				dmang.increment();
				dt = new MDVoidDataType(dmang);
				break;
			case MDMang.DONE:
				throw new MDException("Type code not expected: " + code);
			default:
				dt = parsePrimaryDataType(dmang, isHighest);
				break;
		}
		return dt;
	}
This method parses all data types.  Specifically, it parses void, data indirect types,
function indirect types, and all types parsed by parsePrimaryDataType().
@param dmang - the MDMang driver
@param isHighest - boolean indicating whether something else modifies or names the data
 type to be parsed, which impacts when certain overloaded CV modifiers can be applied.
@return - a type derived from MDDataType
@throws MDException on parsing error
Ghidra/Features/MicrosoftDmang/src/main/java/mdemangler/datatype/MDDataTypeParser.java