public boolean createVirtualTable(CategoryPath categoryPath, String mangled, Address address,
			TaskMonitor monitor) {

		Address a = vxtAddressByMangled.get(mangled);
		if (a != null) {
			if (!a.equals(address)) {
				Msg.warn(this, String.format("New address (%s) does not match existing %s for: %s",
					a, address, mangled));
			}
			else {
				Msg.warn(this,
					String.format("Entry already exists: address (%s), %s", address, mangled));
			}
			return false;
		}
		vxtAddressByMangled.put(mangled, address);

		DemanglerResults demanglerResults = getOwnerAndUsersDtp(categoryPath, mangled);
		if (demanglerResults == null) {
			Msg.warn(this, "Problem obtaining path information from mangled symbol: " + mangled);
			return false;
		}

		OwnerAndParentage ownerAndParentage = demanglerResults.ownerAndParentage();
		ClassID owner = ownerAndParentage.owner();
		List<ClassID> parentage = ownerAndParentage.parentage();
		ParentageNode node = parentageNodeByMangled.get(mangled);
		if (node == null) {
			ParentageNode root = demanglerResults.vtType().equals(VtType.VBT) ? vbtRoot : vftRoot;
			node = getOrAddParentageNode(categoryPath, root, demanglerResults);
			if (node == null) {
				return false;
			}
			parentageNodeByMangled.put(mangled, node);
		}

		switch (demanglerResults.vtType()) {
			case VBT:
				ProgramVirtualBaseTable prvbt = new ProgramVirtualBaseTable(owner, parentage,
					program, address, ClassUtils.getVbtEntrySize(ctm.getDataTypeManager()),
					mangled);
				if (node.getVBTable() != null) {
					Msg.warn(this, "VBT already exists at node for " + mangled);
					return false;
				}
				node.setVBTable(prvbt);
				vbtByAddress.put(address, prvbt);
				storeVbt(owner, address, prvbt); // temp solution?
				break;

			case VFT:
				ProgramVirtualFunctionTable vft = new ProgramVirtualFunctionTable(owner, parentage,
					program, address, ctm.getDefaultVfTableElementSize(), mangled);
				if (node.getVFTable() != null) {
					Msg.warn(this, "VFT already exists at node for " + mangled);
					return false;
				}
				node.setVFTable(vft);
				vftByAddress.put(address, vft);
				storeVft(owner, address, vft); // temp solution?
				break;

			default:
				throw new AssertException("Unhandled VtType: " + demanglerResults.vtType());
		}
		return true;
	}
Creates a virtual function or base table for the mangled symbol and its associated
memory address

@param categoryPath the base category path used for the collection of class-related
types
@param mangled the mangled name of the type
@param address the address associated with the mangled name
@param monitor the task monitor
@return {@code true} if successful
Ghidra/Features/PDB/src/main/java/ghidra/app/util/pdb/classtype/MsVxtManager.java