private Address getPrimaryVtableAddress(Address typeinfoRef, GccTypeinfo typeinfo)
			throws CancelledException {

		if (typeinfoRef == null) {
			return null;
		}
		// get the data containing the typeinfo reference
		Data dataContaining = listing.getDataContaining(typeinfoRef);
		if (dataContaining != null && dataContaining.isDefined()) {

			// get the top address of the containing data
			Address dataAddress = dataContaining.getAddress();

			// if it has a vtable label then return the data address
			boolean hasVtableLabel = hasSymbolWithName(dataAddress, VTABLE_LABEL) ||
				hasSymbolWithName(dataAddress, CONSTRUCTION_VTABLE_LABEL);
			if (hasVtableLabel) {
				return dataAddress;
			}

			// if data has imported symbol and no symbols named vtable then it isn't a
			// vtable
			// checking this way checks both imported actual symbols and imported mangled
			// symbols with analysis demangled symbols
			if (hasImportedSymbol(dataAddress) && !hasVtableLabel) {
				return null;
			}

		}

		// check the long just before and if not a zero then continue since the rest
		// are internal vtables and will get processed when the main one does
		Address offsetToTop = getAddress(typeinfoRef, 0 - defaultPointerSize);

		// check for appropriately sized long that is value 0 to make sure the
		// vtable the typeinfo ref is in is the main one and skip otherwise since
		// non-zero
		// ones are internal vtables that will get processed with the main one
		if (!extendedFlatAPI.hasNumZeros(offsetToTop, defaultPointerSize)) {
			return null;
		}

		Address vtableAddress = offsetToTop;

		// NEW CHECK: check to see if referenced typeinfo is  non-inheritance type and if so
		// return the current value of vtableAddress as there is only one long (zeres) for 
		// vtables referencing non-inh class typeinfos
		if (typeinfo.isClassTypeinfo()) {
			return vtableAddress;
		}

		// start with last verified part of possible vtable and continue going backwards
		// until top of vtable is found
		// stop if top of mem block
		// stop if bytes are an address
		// stop if referenced
		// are they ever zero - not that i have seen so far in the last vftable
		// if pointer to something or valid address or is in a structure

		MemoryBlock currentBlock = program.getMemory().getBlock(typeinfoRef);

		while (vtableAddress != null) {

			boolean hasVtableLabel = hasSymbolWithName(vtableAddress, VTABLE_LABEL) ||
				hasSymbolWithName(vtableAddress, CONSTRUCTION_VTABLE_LABEL);
			if (hasVtableLabel) {
				return vtableAddress;
			}

			// if address has imported symbol and no symbols named vtable then it isn't a
			// vtable
			// checking this way checks both imported actual symbols and imported mangled
			// symbols with analysis demangled symbols
			if (hasImportedSymbol(vtableAddress) && !hasVtableLabel) {
				return null;
			}

			if (getPointerToDefinedMemory(vtableAddress) != null) {
				return vtableAddress.add(defaultPointerSize);
			}

			MemoryBlock memoryBlock = program.getMemory().getBlock(vtableAddress);
			if (memoryBlock == null || !memoryBlock.equals(currentBlock)) {
				return vtableAddress.add(defaultPointerSize);
			}

			Data data = listing.getDataContaining(vtableAddress);
			if (data != null && !data.getDataType().getName().contains("undefined")) {
				return vtableAddress.add(defaultPointerSize);
			}

			vtableAddress = getAddress(vtableAddress, 0 - defaultPointerSize);
		}

		return null;

	}
method to find the main vtable for the given typeinfo and if any, add the
construction ones to the passed in list

@param typeinfo
@param map
@param constructionVtables
@param numBaseRefs
@return address of main vtable for this class
@throws CancelledException
Ghidra/Features/Decompiler/ghidra_scripts/classrecovery/RTTIGccClassRecoverer.java