TypeIndex TypeInfoCache::get_index(TypeInfoPtr candidate, TypeInfoPtr class_type) { TypeIndex index; TypeIndex class_index; auto iter = info_to_index.find(KeyWrapper<AbstractTypeInfo>(candidate)); if (iter != info_to_index.end()) index = iter->second; else { auto class_iter = info_to_index.find(KeyWrapper<AbstractTypeInfo>(class_type)); if (class_iter != info_to_index.end()) class_index = class_iter->second; else { class_index = TypeIndex(index_to_info.size(), index_to_info.size()); info_to_index[class_type] = class_index; index_to_info.push_back(class_type); } if (*candidate == *class_type) index = class_index; else { index = TypeIndex(index_to_info.size(), class_index.id); info_to_index[candidate] = index; index_to_info.push_back(candidate); } } return index; }
unsigned UserDefinedCodeViewTypesBuilder::GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, const DataFieldDescriptor *FieldsDescriptors, const StaticDataFieldDescriptor *StaticsDescriptors) { FieldListRecordBuilder FLBR(TypeTable); FLBR.begin(); uint16_t memberCount = 0; if (!ClassDescriptor.IsStruct) { memberCount++; AddClassVTShape(FLBR); } if (ClassDescriptor.BaseClassId != 0) { memberCount++; AddBaseClass(FLBR, ClassDescriptor.BaseClassId); } for (int i = 0; i < ClassFieldsDescriptor.FieldsCount; ++i) { DataFieldDescriptor desc = FieldsDescriptors[i]; MemberAccess Access = MemberAccess::Public; TypeIndex MemberBaseType(desc.FieldTypeIndex); if (desc.Offset == 0xFFFFFFFF) { StaticDataMemberRecord SDMR(Access, MemberBaseType, desc.Name); FLBR.writeMemberType(SDMR); } else { int MemberOffsetInBytes = desc.Offset; DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes, desc.Name); FLBR.writeMemberType(DMR); } memberCount++; } TypeIndex FieldListIndex = FLBR.end(true); TypeRecordKind Kind = ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class; ClassOptions CO = GetCommonClassOptions(); ClassRecord CR(Kind, memberCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), ClassFieldsDescriptor.Size, ClassDescriptor.Name, StringRef()); TypeIndex ClassIndex = TypeTable.writeKnownType(CR); UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, ClassIndex.getIndex())); return ClassIndex.getIndex(); }
StringRef ScalarTraits<codeview::TypeIndex>::input(StringRef Scalar, void *Ctx, codeview::TypeIndex &S) { uint32_t I; StringRef Result = ScalarTraits<uint32_t>::input(Scalar, Ctx, I); if (!Result.empty()) return Result; S = TypeIndex(I); return ""; }
unsigned UserDefinedCodeViewTypesBuilder::GetEnumTypeIndex( const EnumTypeDescriptor &TypeDescriptor, const EnumRecordTypeDescriptor *TypeRecords) { ClassOptions CO = GetCommonClassOptions(); unsigned FieldListIndex = GetEnumFieldListType(TypeDescriptor.ElementCount, TypeRecords); TypeIndex FieldListIndexType = TypeIndex(FieldListIndex); TypeIndex ElementTypeIndex = TypeIndex(TypeDescriptor.ElementType); EnumRecord EnumRecord(TypeDescriptor.ElementCount, CO, FieldListIndexType, TypeDescriptor.Name, StringRef(), ElementTypeIndex); TypeIndex Type = TypeTable.writeKnownType(EnumRecord); UserDefinedTypes.push_back(std::make_pair(TypeDescriptor.Name, Type.getIndex())); return Type.getIndex(); }
unsigned UserDefinedCodeViewTypesBuilder::GetPointerTypeIndex(const PointerTypeDescriptor& PointerDescriptor) { uint32_t elementType = PointerDescriptor.ElementType; PointerKind pointerKind = PointerDescriptor.Is64Bit ? PointerKind::Near64 : PointerKind::Near32; PointerMode pointerMode = PointerDescriptor.IsReference ? PointerMode::LValueReference : PointerMode::Pointer; PointerOptions pointerOptions = PointerDescriptor.IsConst ? PointerOptions::Const : PointerOptions::None; PointerRecord PointerToClass(TypeIndex(elementType), pointerKind, pointerMode, pointerOptions, 0); TypeIndex PointerIndex = TypeTable.writeKnownType(PointerToClass); return PointerIndex.getIndex(); }
DrmPlane::TypeIndex DrmPlane::type() { uint64_t value = propValue(int(PropertyIndex::Type)); int typeCount = int(TypeIndex::Count); for (int i = 0; i < typeCount; i++) { if (m_props[int(PropertyIndex::Type)]->enumMap(i) == value) { return TypeIndex(i); } } return TypeIndex::Overlay; }
namespace members { static BaseClassRecord BaseClass(MemberAccess::Public, TypeIndex(47), 0); static EnumeratorRecord Enumerator(MemberAccess::Public, APSInt(APInt(8, 3, false)), "Test"); DataMemberRecord DataMember(MemberAccess::Public, TypeIndex(48), 0, "Test"); OverloadedMethodRecord OverloadedMethod(3, TypeIndex(49), "MethodList"); static struct { const TypeIndex T1{50}; const TypeIndex T2{51}; const TypeIndex T3{52}; const TypeIndex T4{53}; OneMethodRecord R1{T1, MemberAccess::Public, MethodKind::IntroducingVirtual, MethodOptions::None, 0, "M1"}; OneMethodRecord R2{T2, MemberAccess::Public, MethodKind::PureVirtual, MethodOptions::None, 0, "M2"}; OneMethodRecord R3{T3, MemberAccess::Public, MethodKind::PureIntroducingVirtual, MethodOptions::None, 0, "M3"}; OneMethodRecord R4{T4, MemberAccess::Protected, MethodKind::Vanilla, MethodOptions::CompilerGenerated, 0, "M4"}; } OneMethod; static NestedTypeRecord NestedType(TypeIndex(54), "MyClass"); static StaticDataMemberRecord StaticDataMember(MemberAccess::Public, TypeIndex(55), "Foo"); static VirtualBaseClassRecord VirtualBaseClass(TypeRecordKind::VirtualBaseClass, MemberAccess::Public, TypeIndex(56), TypeIndex(57), 0, 0); static VFPtrRecord VFPtr(TypeIndex(58)); static ListContinuationRecord Continuation(TypeIndex(59)); }
unsigned UserDefinedCodeViewTypesBuilder::GetClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor) { TypeRecordKind Kind = ClassDescriptor.IsStruct ? TypeRecordKind::Struct : TypeRecordKind::Class; ClassOptions CO = ClassOptions::ForwardReference | GetCommonClassOptions(); TypeIndex FieldListIndex = TypeIndex(); uint16_t memberCount = 0; if (!ClassDescriptor.IsStruct) { FieldListRecordBuilder FLBR(TypeTable); FLBR.begin(); memberCount++; AddClassVTShape(FLBR); FieldListIndex = FLBR.end(true); } ClassRecord CR(Kind, memberCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), 0, ClassDescriptor.Name, StringRef()); TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR); return FwdDeclTI.getIndex(); }
unsigned UserDefinedCodeViewTypesBuilder::GetPrimitiveTypeIndex(PrimitiveTypeFlags Type) { switch (Type) { case PrimitiveTypeFlags::Void: return TypeIndex::Void().getIndex(); case PrimitiveTypeFlags::Boolean: return TypeIndex(SimpleTypeKind::Boolean8).getIndex(); case PrimitiveTypeFlags::Char: return TypeIndex::WideCharacter().getIndex(); case PrimitiveTypeFlags::SByte: return TypeIndex(SimpleTypeKind::SByte).getIndex(); case PrimitiveTypeFlags::Byte: return TypeIndex(SimpleTypeKind::Byte).getIndex(); case PrimitiveTypeFlags::Int16: return TypeIndex(SimpleTypeKind::Int16).getIndex(); case PrimitiveTypeFlags::UInt16: return TypeIndex(SimpleTypeKind::UInt16).getIndex(); case PrimitiveTypeFlags::Int32: return TypeIndex::Int32().getIndex(); case PrimitiveTypeFlags::UInt32: return TypeIndex::UInt32().getIndex(); case PrimitiveTypeFlags::Int64: return TypeIndex::Int64().getIndex(); case PrimitiveTypeFlags::UInt64: return TypeIndex::UInt64().getIndex(); case PrimitiveTypeFlags::Single: return TypeIndex::Float32().getIndex(); case PrimitiveTypeFlags::Double: return TypeIndex::Float64().getIndex(); case PrimitiveTypeFlags::IntPtr: case PrimitiveTypeFlags::UIntPtr: return TargetPointerSize == 4 ? TypeIndex::VoidPointer32().getIndex() : TypeIndex::VoidPointer64().getIndex(); default: assert(false && "Unexpected type"); return 0; } }
void CodeViewDebug::emitTypeInformation() { // Start the .debug$T section with 0x4. Asm->OutStreamer->SwitchSection( Asm->getObjFileLowering().getCOFFDebugTypesSection()); Asm->EmitInt32(COFF::DEBUG_SECTION_MAGIC); NamedMDNode *CU_Nodes = Asm->MMI->getModule()->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return; // This type info currently only holds function ids for use with inline call // frame info. All functions are assigned a simple 'void ()' type. Emit that // type here. TypeIndex ArgListIdx = getNextTypeIndex(); Asm->EmitInt16(2 + sizeof(ArgList)); Asm->EmitInt16(LF_ARGLIST); Asm->EmitInt32(0); TypeIndex VoidProcIdx = getNextTypeIndex(); Asm->EmitInt16(2 + sizeof(ProcedureType)); Asm->EmitInt16(LF_PROCEDURE); ProcedureType Proc{}; // Zero initialize. Proc.ReturnType = TypeIndex::Void(); Proc.CallConv = CallingConvention::NearC; Proc.Options = FunctionOptions::None; Proc.NumParameters = 0; Proc.ArgListType = ArgListIdx; emitRecord(*Asm->OutStreamer, Proc); for (MDNode *N : CU_Nodes->operands()) { auto *CUNode = cast<DICompileUnit>(N); for (auto *SP : CUNode->getSubprograms()) { StringRef DisplayName = SP->getDisplayName(); Asm->EmitInt16(2 + sizeof(FuncId) + DisplayName.size() + 1); Asm->EmitInt16(LF_FUNC_ID); FuncId Func{}; // Zero initialize. Func.ParentScope = TypeIndex(); Func.FunctionType = VoidProcIdx; emitRecord(*Asm->OutStreamer, Func); Asm->OutStreamer->EmitBytes(DisplayName); Asm->EmitInt8(0); TypeIndex FuncIdIdx = getNextTypeIndex(); SubprogramToFuncId.insert(std::make_pair(SP, FuncIdIdx)); } } }
unsigned UserDefinedCodeViewTypesBuilder::GetMemberFunctionTypeIndex(const MemberFunctionTypeDescriptor& MemberDescriptor, uint32_t const *const ArgumentTypes) { std::vector<TypeIndex> argumentTypes; argumentTypes.reserve(MemberDescriptor.NumberOfArguments); for (uint16_t iArgument = 0; iArgument < MemberDescriptor.NumberOfArguments; iArgument++) { argumentTypes.emplace_back(ArgumentTypes[iArgument]); } ArgListRecord ArgList(TypeRecordKind::ArgList, argumentTypes); TypeIndex ArgumentList = TypeTable.writeKnownType(ArgList); MemberFunctionRecord MemberFunction(TypeIndex(MemberDescriptor.ReturnType), TypeIndex(MemberDescriptor.ContainingClass), TypeIndex(MemberDescriptor.TypeIndexOfThisPointer), CallingConvention(MemberDescriptor.CallingConvention), FunctionOptions::None, MemberDescriptor.NumberOfArguments, ArgumentList, MemberDescriptor.ThisAdjust); TypeIndex MemberFunctionIndex = TypeTable.writeKnownType(MemberFunction); return MemberFunctionIndex.getIndex(); }
inline TypeIndex class_type() const { return TypeIndex(class_id, class_id); }
unsigned UserDefinedCodeViewTypesBuilder::GetMemberFunctionId(const MemberFunctionIdTypeDescriptor& MemberIdDescriptor) { MemberFuncIdRecord MemberFuncId(TypeIndex(MemberIdDescriptor.MemberFunction), TypeIndex(MemberIdDescriptor.ParentClass), MemberIdDescriptor.Name); TypeIndex MemberFuncIdIndex = TypeTable.writeKnownType(MemberFuncId); return MemberFuncIdIndex.getIndex(); }
unsigned UserDefinedCodeViewTypesBuilder::GetArrayTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ArrayTypeDescriptor &ArrayDescriptor) { FieldListRecordBuilder FLBR(TypeTable); FLBR.begin(); unsigned Offset = 0; unsigned FieldsCount = 0; assert(ClassDescriptor.BaseClassId != 0); AddClassVTShape(FLBR); FieldsCount++; AddBaseClass(FLBR, ClassDescriptor.BaseClassId); FieldsCount++; Offset += TargetPointerSize; MemberAccess Access = MemberAccess::Public; TypeIndex IndexType = TypeIndex(SimpleTypeKind::Int32); DataMemberRecord CountDMR(Access, IndexType, Offset, "count"); FLBR.writeMemberType(CountDMR); FieldsCount++; Offset += TargetPointerSize; if (ArrayDescriptor.IsMultiDimensional == 1) { for (unsigned i = 0; i < ArrayDescriptor.Rank; ++i) { DataMemberRecord LengthDMR(Access, TypeIndex(SimpleTypeKind::Int32), Offset, ArrayDimentions.GetLengthName(i)); FLBR.writeMemberType(LengthDMR); FieldsCount++; Offset += 4; } for (unsigned i = 0; i < ArrayDescriptor.Rank; ++i) { DataMemberRecord BoundsDMR(Access, TypeIndex(SimpleTypeKind::Int32), Offset, ArrayDimentions.GetBoundsName(i)); FLBR.writeMemberType(BoundsDMR); FieldsCount++; Offset += 4; } } TypeIndex ElementTypeIndex = TypeIndex(ArrayDescriptor.ElementType); ArrayRecord AR(ElementTypeIndex, IndexType, ArrayDescriptor.Size, ""); TypeIndex ArrayIndex = TypeTable.writeKnownType(AR); DataMemberRecord ArrayDMR(Access, ArrayIndex, Offset, "values"); FLBR.writeMemberType(ArrayDMR); FieldsCount++; TypeIndex FieldListIndex = FLBR.end(true); assert(ClassDescriptor.IsStruct == false); TypeRecordKind Kind = TypeRecordKind::Class; ClassOptions CO = GetCommonClassOptions(); ClassRecord CR(Kind, FieldsCount, CO, FieldListIndex, TypeIndex(), TypeIndex(), ArrayDescriptor.Size, ClassDescriptor.Name, StringRef()); TypeIndex ClassIndex = TypeTable.writeKnownType(CR); UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, ClassIndex.getIndex())); return ClassIndex.getIndex(); }
namespace leafs { static FuncIdRecord FuncId(TypeIndex(1), TypeIndex(2), "FuncId"); static MemberFuncIdRecord MemFuncId(TypeIndex(3), TypeIndex(4), "FuncId"); static StringIdRecord StringId(TypeIndex(5), "TheString"); static struct { std::vector<TypeIndex> Ids = {TypeIndex(6), TypeIndex(7), TypeIndex(8)}; StringListRecord Record{TypeRecordKind::StringList, Ids}; } StringList; static struct { std::vector<TypeIndex> Ids = {TypeIndex(9), TypeIndex(10), TypeIndex(11)}; BuildInfoRecord Record{Ids}; } BuildInfo; static UdtSourceLineRecord UdtSourceLine(TypeIndex(12), TypeIndex(13), 0); static UdtModSourceLineRecord UdtModSourceLine(TypeIndex(14), TypeIndex(15), 0, 0); static ModifierRecord Modifier(TypeIndex(16), ModifierOptions::None); static ProcedureRecord Procedure(TypeIndex(17), CallingConvention::PpcCall, FunctionOptions::None, 0, TypeIndex(18)); static MemberFunctionRecord MemberFunction(TypeIndex(19), TypeIndex(20), TypeIndex(21), CallingConvention::ThisCall, FunctionOptions::None, 2, TypeIndex(22), 0); static struct { std::vector<TypeIndex> Ids = {TypeIndex(23), TypeIndex(24), TypeIndex(25)}; ArgListRecord Record{TypeRecordKind::ArgList, Ids}; } ArgList; static ArrayRecord Array(TypeIndex(26), TypeIndex(27), 10, "MyArray"); static ClassRecord Class(TypeRecordKind::Class, 3, ClassOptions::None, TypeIndex(28), TypeIndex(29), TypeIndex(30), 10, "MyClass", "MyClassUniqueName"); static ClassRecord Struct(TypeRecordKind::Struct, 3, ClassOptions::None, TypeIndex(31), TypeIndex(32), TypeIndex(33), 10, "MyClass", "MyClassUniqueName"); static UnionRecord Union(1, ClassOptions::None, TypeIndex(34), 10, "MyUnion", "MyUnionUniqueName"); static EnumRecord Enum(1, ClassOptions::None, TypeIndex(35), "MyEnum", "EnumUniqueName", TypeIndex(36)); static BitFieldRecord BitField(TypeIndex(37), 1, 0); static VFTableRecord VFTable(TypeIndex(38), TypeIndex(39), 1, "VFT", {}); static VFTableShapeRecord VTableShape({}); static struct { const TypeIndex T1{40}; const TypeIndex T2{41}; const TypeIndex T3{42}; const TypeIndex T4{43}; std::vector<OneMethodRecord> Methods{ {T1, MemberAccess::Public, MethodKind::IntroducingVirtual, MethodOptions::None, 0, "Method1"}, {T2, MemberAccess::Public, MethodKind::PureVirtual, MethodOptions::None, 0, "Method1"}, {T3, MemberAccess::Public, MethodKind::PureIntroducingVirtual, MethodOptions::None, 0, "Method1"}, {T4, MemberAccess::Public, MethodKind::Static, MethodOptions::None, 0, "Method1"}}; MethodOverloadListRecord Record{Methods}; } MethodOverloadList; static PointerRecord Pointer(TypeIndex(44), PointerKind::Near32, PointerMode::Pointer, PointerOptions::Const, 3); static PointerRecord MemberPointer( TypeIndex(45), PointerKind::Near32, PointerMode::PointerToDataMember, PointerOptions::Const, 3, MemberPointerInfo(TypeIndex(46), PointerToMemberRepresentation::GeneralData)); }
void CParmStatDlg::InitFunc() { m_FuncIndex = FuncIndex(m_Func); m_DstType = TypeIndex(m_Func); }