| 820 | } |
| 821 | |
| 822 | void COFF::CvParseMembers(DbgType* parentType, int tagIdx, bool ipi) |
| 823 | { |
| 824 | if (tagIdx == NULL) |
| 825 | return; |
| 826 | |
| 827 | auto& reader = ipi ? mCvIPIReader : mCvTypeSectionReader; |
| 828 | int offset = ipi ? mCvIPITagStartMap[tagIdx - mCvIPIMinTag] : mCvTagStartMap[tagIdx - mCvMinTag]; |
| 829 | |
| 830 | uint8* data = reader.GetTempPtr(offset, 4); |
| 831 | uint16 trLength = *(uint16*)data; |
| 832 | offset += 2; |
| 833 | data = reader.GetTempPtr(offset, trLength, true); |
| 834 | CvAutoReleaseTempData releaseTempData(this, data); |
| 835 | |
| 836 | uint8* dataStart = data; |
| 837 | uint8* dataEnd = data + trLength; |
| 838 | int16 trLeafType = GET(int16); |
| 839 | bool strMadeCopy; |
| 840 | |
| 841 | auto _ParseString = [&]() |
| 842 | { |
| 843 | strMadeCopy = false; |
| 844 | int nameLen = strlen((const char*)data); |
| 845 | int nameOfs = data - dataStart; |
| 846 | const char* name = (const char*)reader.GetPermanentPtr(offset + nameOfs, nameLen + 1, &strMadeCopy); |
| 847 | data += nameLen + 1; |
| 848 | return name; |
| 849 | }; |
| 850 | |
| 851 | if (trLeafType == 0) |
| 852 | return; |
| 853 | switch (trLeafType) |
| 854 | { |
| 855 | case LF_FIELDLIST: |
| 856 | { |
| 857 | uint8* sectionStart = data; |
| 858 | |
| 859 | while (data < dataEnd) |
| 860 | { |
| 861 | uint8* leafDataStart = data; |
| 862 | int leafType = (int)GET(uint16); |
| 863 | switch (leafType) |
| 864 | { |
| 865 | case LF_VFUNCTAB: |
| 866 | { |
| 867 | lfVFuncTab& vfuncTab = *(lfVFuncTab*)leafDataStart; |
| 868 | |
| 869 | DbgType* vtableType = CvGetType(vfuncTab.type); |
| 870 | |
| 871 | BP_ALLOC_T(DbgVariable); |
| 872 | DbgVariable* vtableMember = mAlloc.Alloc<DbgVariable>(); |
| 873 | vtableMember->mType = vtableType; |
| 874 | parentType->mMemberList.PushFront(vtableMember); |
| 875 | |
| 876 | data = (uint8*)(&vfuncTab + 1); |
| 877 | } |
| 878 | break; |
| 879 | case LF_BCLASS: |
nothing calls this directly
no test coverage detected