diff options
author | Konstantin Baladurin <k.baladurin@partner.samsung.com> | 2018-06-14 00:49:19 +0300 |
---|---|---|
committer | Jan Kotas <jkotas@microsoft.com> | 2018-06-14 00:49:19 +0300 |
commit | 80000c509b76c3920e780a993f376b21e0cb9a82 (patch) | |
tree | 10cf8c8db1ef4f0847b7443fd41239de6bcd51da /src/Native | |
parent | b568db3a9078d9973b78222d2778a4e2cd88bab4 (diff) |
Dwarf: add support for static members (#5592)
- change CU lang from C89 to C_plus_plus
- ungroup gc, non-gc and thread statics in debuginfo
Diffstat (limited to 'src/Native')
9 files changed, 198 insertions, 30 deletions
diff --git a/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.cpp b/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.cpp index 76c307ba5..d3af316ca 100644 --- a/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.cpp +++ b/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.cpp @@ -110,7 +110,8 @@ unsigned UserDefinedCodeViewTypesBuilder::GetClassTypeIndex( unsigned UserDefinedCodeViewTypesBuilder::GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) { + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) { FieldListRecordBuilder FLBR(TypeTable); FLBR.begin(); diff --git a/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.h b/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.h index 46815f685..5534cc7d3 100644 --- a/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.h +++ b/src/Native/ObjWriter/debugInfo/codeView/codeViewTypeBuilder.h @@ -40,7 +40,8 @@ public: unsigned GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) override; + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) override; unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor, const ArrayTypeDescriptor &ArrayDescriptor) override; diff --git a/src/Native/ObjWriter/debugInfo/dwarf/dwarfAbbrev.cpp b/src/Native/ObjWriter/debugInfo/dwarf/dwarfAbbrev.cpp index c32163d51..23ee3fa30 100644 --- a/src/Native/ObjWriter/debugInfo/dwarf/dwarfAbbrev.cpp +++ b/src/Native/ObjWriter/debugInfo/dwarf/dwarfAbbrev.cpp @@ -223,6 +223,7 @@ void Dump(MCObjectStreamer *Streamer, uint16_t DwarfVersion, unsigned TargetPoin dwarf::DW_AT_name, dwarf::DW_FORM_strp, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, dwarf::DW_AT_external, dwarf::DW_FORM_flag_present, + dwarf::DW_AT_declaration, dwarf::DW_FORM_flag_present, 0, 0, PointerType, diff --git a/src/Native/ObjWriter/debugInfo/dwarf/dwarfGen.cpp b/src/Native/ObjWriter/debugInfo/dwarf/dwarfGen.cpp index 5c32ed56b..518608673 100644 --- a/src/Native/ObjWriter/debugInfo/dwarf/dwarfGen.cpp +++ b/src/Native/ObjWriter/debugInfo/dwarf/dwarfGen.cpp @@ -541,6 +541,84 @@ void LexicalScope::Dump(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObjectStrea } } +// StaticVarInfo + +class StaticVarInfo : public DwarfInfo +{ +public: + StaticVarInfo(const DwarfStaticDataField *StaticField) : StaticField(StaticField) {} + + void Dump(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObjectStreamer *Streamer, + MCSection *TypeSection, MCSection *StrSection) override; + +protected: + void DumpStrings(MCObjectStreamer *Streamer) override {}; + void DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) override; + +private: + const DwarfStaticDataField *StaticField; + + void EmitLocation(MCObjectStreamer *Streamer); +}; + +void StaticVarInfo::Dump(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObjectStreamer *Streamer, + MCSection *TypeSection, MCSection *StrSection) { + MCContext &context = Streamer->getContext(); + MCSymbol *Sym = context.getOrCreateSymbol(Twine(StaticField->GetStaticDataName())); + if (Sym->isUndefined()) + return; + + DwarfInfo::Dump(TypeBuilder, Streamer, TypeSection, StrSection); +} + +void StaticVarInfo::DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) { + // Abbrev Number + Streamer->EmitULEB128IntValue(DwarfAbbrev::VariableStatic); + + // DW_AT_specification + EmitInfoOffset(Streamer, StaticField, 4); + + // DW_AT_location + EmitLocation(Streamer); +} + +void StaticVarInfo::EmitLocation(MCObjectStreamer *Streamer) { + MCContext &context = Streamer->getContext(); + unsigned TargetPointerSize = context.getAsmInfo()->getCodePointerSize(); + + MCSymbol *Sym = context.getOrCreateSymbol(Twine(StaticField->GetStaticDataName())); + + SmallString<128> Tmp; + raw_svector_ostream OSE(Tmp); + encodeULEB128(StaticField->GetStaticOffset(), OSE); + StringRef OffsetRepr = OSE.str(); + + unsigned Len = 1 /* DW_OP_addr */ + TargetPointerSize; + + // Need double deref + if (StaticField->IsStaticDataInObject()) { + Len += (1 /* DW_OP_deref */) * 2; + } + + if (StaticField->GetStaticOffset() != 0) { + Len += 1 /* DW_OP_plus_uconst */ + OffsetRepr.size(); + } + + Streamer->EmitULEB128IntValue(Len); + Streamer->EmitIntValue(dwarf::DW_OP_addr, 1); + Streamer->EmitSymbolValue(Sym, TargetPointerSize); + + if (StaticField->IsStaticDataInObject()) { + Streamer->EmitIntValue(dwarf::DW_OP_deref, 1); + Streamer->EmitIntValue(dwarf::DW_OP_deref, 1); + } + + if (StaticField->GetStaticOffset() != 0) { + Streamer->EmitIntValue(dwarf::DW_OP_plus_uconst, 1); + Streamer->EmitBytes(OffsetRepr); + } +} + // VarInfo VarInfo::VarInfo(const DebugVarInfo &Info, bool IsThis) : @@ -842,7 +920,7 @@ void DwarfGen::EmitCompileUnit() { #ifdef FEATURE_LANGID_CS Streamer->EmitIntValue(DW_LANG_MICROSOFT_CSHARP, 2); #else - Streamer->EmitIntValue(dwarf::DW_LANG_C89, 2); + Streamer->EmitIntValue(dwarf::DW_LANG_C_plus_plus, 2); #endif // DW_AT_stmt_list @@ -910,7 +988,7 @@ void DwarfGen::EmitAranges() { // The 4 byte length not including the 4 byte value for the length. Streamer->EmitIntValue(Length - 4, 4); - // he 2 byte version, which is 2. + // The 2 byte version, which is 2. Streamer->EmitIntValue(2, 2); // The 4 byte offset to the compile unit in the .debug_info from the start @@ -965,6 +1043,15 @@ void DwarfGen::Finish() { Subprogram.Dump(TypeBuilder, Streamer, InfoSection, StrSection, LocSection); } + // Dump static vars + + for (const auto *ClassTypeInfo : TypeBuilder->GetClassesWithStaticFields()) { + for (const auto &StaticField : ClassTypeInfo->GetStaticFields()) { + StaticVarInfo Info(&StaticField); + Info.Dump(TypeBuilder, Streamer, InfoSection, StrSection); + } + } + // Add the NULL terminating the Compile Unit DIE's. Streamer->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); diff --git a/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.cpp b/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.cpp index 736162072..da5448bf1 100644 --- a/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.cpp +++ b/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.cpp @@ -97,7 +97,7 @@ void DwarfInfo::EmitOffset(MCObjectStreamer *Streamer, Streamer->EmitValue(OffsetExpr, Size); } -void DwarfInfo::EmitInfoOffset(MCObjectStreamer *Streamer, DwarfInfo *Info, unsigned Size) { +void DwarfInfo::EmitInfoOffset(MCObjectStreamer *Streamer, const DwarfInfo *Info, unsigned Size) { uint64_t Offset = Info->InfoSymbol->getOffset(); if (Offset != 0) { Streamer->EmitIntValue(Offset, Size); @@ -299,7 +299,7 @@ void DwarfDataField::DumpTypes(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObje void DwarfDataField::DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) { // Abbrev Number - Streamer->EmitULEB128IntValue(IsStatic ? DwarfAbbrev::ClassMemberStatic : DwarfAbbrev::ClassMember); + Streamer->EmitULEB128IntValue(DwarfAbbrev::ClassMember); // DW_AT_name EmitSectionOffset(Streamer, StrSymbol, 4); @@ -309,24 +309,43 @@ void DwarfDataField::DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTy assert(MemberTypeInfo != nullptr); EmitInfoOffset(Streamer, MemberTypeInfo, 4); - if (!IsStatic) { - // DW_AT_data_member_location - Streamer->EmitIntValue(Offset, 4); - } + // DW_AT_data_member_location + Streamer->EmitIntValue(Offset, 4); +} + +// DwarfStaticDataField + +void DwarfStaticDataField::DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) { + // Abbrev Number + Streamer->EmitULEB128IntValue(DwarfAbbrev::ClassMemberStatic); + + // DW_AT_name + EmitSectionOffset(Streamer, StrSymbol, 4); + + // DW_AT_type + DwarfInfo *MemberTypeInfo = TypeBuilder->GetTypeInfoByIndex(TypeIndex); + assert(MemberTypeInfo != nullptr); + EmitInfoOffset(Streamer, MemberTypeInfo, 4); } // DwarfClassTypeInfo DwarfClassTypeInfo::DwarfClassTypeInfo(const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) : + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) : Name(ClassDescriptor.Name), IsStruct(ClassDescriptor.IsStruct), BaseClassId(ClassDescriptor.BaseClassId), Size(ClassDescriptor.InstanceSize), IsForwardDecl(false) { + int32_t staticIdx = 0; for (int32_t i = 0; i < ClassFieldsDescriptor.FieldsCount; i++) { - Fields.emplace_back(FieldsDescriptors[i]); + if (FieldsDescriptors[i].Offset == 0xFFFFFFFF) { + StaticFields.emplace_back(FieldsDescriptors[i], StaticsDescriptors[staticIdx++]); + } else { + Fields.emplace_back(FieldsDescriptors[i]); + } } } @@ -348,6 +367,10 @@ void DwarfClassTypeInfo::DumpTypes(UserDefinedDwarfTypesBuilder *TypeBuilder, MC Field.DumpTypes(TypeBuilder, Streamer, TypeSection, StrSection); } + for (auto &StaticField : StaticFields) { + StaticField.DumpTypes(TypeBuilder, Streamer, TypeSection, StrSection); + } + for (auto *Function : MemberFunctions) { Function->DumpTypes(TypeBuilder, Streamer, TypeSection, StrSection); } @@ -367,6 +390,10 @@ void DwarfClassTypeInfo::Dump(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObjec Field.Dump(TypeBuilder, Streamer, TypeSection, StrSection); } + for (auto &StaticField : StaticFields) { + StaticField.Dump(TypeBuilder, Streamer, TypeSection, StrSection); + } + for (auto *Function : MemberFunctions) { Function->Dump(TypeBuilder, Streamer, TypeSection, StrSection); } @@ -634,10 +661,20 @@ unsigned UserDefinedDwarfTypesBuilder::GetClassTypeIndex( unsigned UserDefinedDwarfTypesBuilder::GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) { + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) { unsigned TypeIndex = ArrayIndexToTypeIndex(DwarfTypes.size()); UserDefinedTypes.push_back(std::make_pair(ClassDescriptor.Name, TypeIndex)); - DwarfTypes.push_back(make_unique<DwarfClassTypeInfo>(ClassDescriptor, ClassFieldsDescriptor, FieldsDescriptors)); + + DwarfClassTypeInfo *ClassTypeInfo = new DwarfClassTypeInfo(ClassDescriptor, ClassFieldsDescriptor, + FieldsDescriptors, StaticsDescriptors); + + DwarfTypes.push_back(std::unique_ptr<DwarfClassTypeInfo>(ClassTypeInfo)); + + if (ClassTypeInfo->GetStaticFields().size() > 0) { + ClassesWithStaticFields.push_back(ClassTypeInfo); + } + return TypeIndex; } @@ -669,7 +706,7 @@ unsigned UserDefinedDwarfTypesBuilder::GetArrayTypeIndex( unsigned TypeIndex = ArrayIndexToTypeIndex(DwarfTypes.size()); UserDefinedTypes.push_back(std::make_pair(ArrayClassDescriptor.Name, TypeIndex)); - DwarfTypes.push_back(make_unique<DwarfClassTypeInfo>(ArrayClassDescriptor, FieldsTypeDesc, FieldDescs.data())); + DwarfTypes.push_back(make_unique<DwarfClassTypeInfo>(ArrayClassDescriptor, FieldsTypeDesc, FieldDescs.data(), nullptr)); return TypeIndex; } diff --git a/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.h b/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.h index 6ae937377..0ea43a451 100644 --- a/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.h +++ b/src/Native/ObjWriter/debugInfo/dwarf/dwarfTypeBuilder.h @@ -55,7 +55,7 @@ protected: const MCExpr *OffsetExpr, unsigned Size); - static void EmitInfoOffset(MCObjectStreamer *Streamer, DwarfInfo *Info, unsigned Size); + static void EmitInfoOffset(MCObjectStreamer *Streamer, const DwarfInfo *Info, unsigned Size); MCSymbol *StrSymbol; MCSymbol *InfoSymbol; @@ -129,25 +129,45 @@ public: DwarfDataField(const DataFieldDescriptor &Descriptor) : Name(Descriptor.Name), TypeIndex(Descriptor.FieldTypeIndex), - Offset(Descriptor.Offset), - IsStatic(Offset == 0xFFFFFFFF) {} + Offset(Descriptor.Offset) {} void DumpTypes(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObjectStreamer *Streamer, MCSection *TypeSection, MCSection *StrSection) override; uint32_t GetTypeIndex() const { return TypeIndex; } - bool IsStaticMethod() const { return IsStatic; } + const std::string &GetName() const { return Name; } protected: void DumpStrings(MCObjectStreamer *Streamer) override; void DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) override; -private: std::string Name; uint32_t TypeIndex; uint64 Offset; - bool IsStatic; +}; + +class DwarfStaticDataField : public DwarfDataField +{ +public: + DwarfStaticDataField(const DataFieldDescriptor &Descriptor, + const StaticDataFieldDescriptor &StaticDescriptor) : + DwarfDataField(Descriptor), + StaticDataName(StaticDescriptor.StaticDataName), + StaticOffset(StaticDescriptor.StaticOffset), + StaticDataInObject(StaticDescriptor.IsStaticDataInObject) {} + + const std::string &GetStaticDataName() const { return StaticDataName; } + uint64 GetStaticOffset() const { return StaticOffset; } + bool IsStaticDataInObject() const { return StaticDataInObject; } + +protected: + void DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) override; + +private: + std::string StaticDataName; + uint64 StaticOffset; + bool StaticDataInObject; }; class DwarfMemberFunctionIdTypeInfo; @@ -164,7 +184,8 @@ public: DwarfClassTypeInfo(const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors); + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors); void Dump(UserDefinedDwarfTypesBuilder *TypeBuilder, MCObjectStreamer *Streamer, MCSection *TypeSection, MCSection *StrSection) override; @@ -176,6 +197,10 @@ public: MemberFunctions.push_back(TypeInfo); } + const std::vector<DwarfStaticDataField> &GetStaticFields() const { return StaticFields; } + + const std::string &GetName() const { return Name; } + protected: void DumpStrings(MCObjectStreamer *Streamer) override; void DumpTypeInfo(MCObjectStreamer *Streamer, UserDefinedDwarfTypesBuilder *TypeBuilder) override; @@ -187,6 +212,7 @@ private: uint64 Size; bool IsForwardDecl; std::vector<DwarfDataField> Fields; + std::vector<DwarfStaticDataField> StaticFields; std::vector<DwarfMemberFunctionIdTypeInfo*> MemberFunctions; }; @@ -305,7 +331,8 @@ public: unsigned GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) override; + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) override; unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor, const ArrayTypeDescriptor &ArrayDescriptor) override; @@ -323,6 +350,8 @@ public: unsigned GetSimpleArrayTypeIndex(unsigned ElemIndex, unsigned Size); + const std::vector<DwarfClassTypeInfo*> &GetClassesWithStaticFields() const { return ClassesWithStaticFields; } + private: static const unsigned StartTypeIndex = 1; // Make TypeIndex 0 - Invalid static unsigned TypeIndexToArrayIndex(unsigned TypeIndex) { return TypeIndex - StartTypeIndex; } @@ -332,4 +361,6 @@ private: std::unordered_map<PrimitiveTypeFlags, uint32_t, EnumHash<PrimitiveTypeFlags>> PrimitiveDwarfTypes; // map[ElemTypeIndex][Size] -> ArrTypeIndex std::unordered_map<uint32_t, std::unordered_map<uint32_t, uint32_t>> SimpleArrayDwarfTypes; + + std::vector<DwarfClassTypeInfo*> ClassesWithStaticFields; };
\ No newline at end of file diff --git a/src/Native/ObjWriter/debugInfo/typeBuilder.h b/src/Native/ObjWriter/debugInfo/typeBuilder.h index 69440d9d9..f3e3046e5 100644 --- a/src/Native/ObjWriter/debugInfo/typeBuilder.h +++ b/src/Native/ObjWriter/debugInfo/typeBuilder.h @@ -65,6 +65,12 @@ extern "C" struct DataFieldDescriptor { const char *Name; }; +extern "C" struct StaticDataFieldDescriptor { + const char *StaticDataName; + uint64 StaticOffset; + int IsStaticDataInObject; +}; + extern "C" struct ClassFieldsTypeDescriptior { uint64 Size; int32_t FieldsCount; @@ -125,7 +131,8 @@ public: virtual unsigned GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) = 0; + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) = 0; virtual unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor, const ArrayTypeDescriptor &ArrayDescriptor) = 0; diff --git a/src/Native/ObjWriter/objwriter.cpp b/src/Native/ObjWriter/objwriter.cpp index 3872d7011..4470f04be 100644 --- a/src/Native/ObjWriter/objwriter.cpp +++ b/src/Native/ObjWriter/objwriter.cpp @@ -847,9 +847,10 @@ ObjectWriter::GetClassTypeIndex(const ClassTypeDescriptor &ClassDescriptor) { unsigned ObjectWriter::GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors) { - unsigned res = TypeBuilder->GetCompleteClassTypeIndex( - ClassDescriptor, ClassFieldsDescriptor, FieldsDescriptors); + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors) { + unsigned res = TypeBuilder->GetCompleteClassTypeIndex(ClassDescriptor, + ClassFieldsDescriptor, FieldsDescriptors, StaticsDescriptors); return res; } diff --git a/src/Native/ObjWriter/objwriter.h b/src/Native/ObjWriter/objwriter.h index 5ca6257c8..6c1ba8645 100644 --- a/src/Native/ObjWriter/objwriter.h +++ b/src/Native/ObjWriter/objwriter.h @@ -89,7 +89,8 @@ public: unsigned GetCompleteClassTypeIndex( const ClassTypeDescriptor &ClassDescriptor, const ClassFieldsTypeDescriptior &ClassFieldsDescriptor, - const DataFieldDescriptor *FieldsDescriptors); + const DataFieldDescriptor *FieldsDescriptors, + const StaticDataFieldDescriptor *StaticsDescriptors); unsigned GetArrayTypeIndex(const ClassTypeDescriptor &ClassDescriptor, const ArrayTypeDescriptor &ArrayDescriptor); @@ -316,10 +317,11 @@ DLL_EXPORT unsigned GetClassTypeIndex(ObjectWriter *OW, DLL_EXPORT unsigned GetCompleteClassTypeIndex(ObjectWriter *OW, ClassTypeDescriptor ClassDescriptor, ClassFieldsTypeDescriptior ClassFieldsDescriptor, - DataFieldDescriptor *FieldsDescriptors) { + DataFieldDescriptor *FieldsDescriptors, + StaticDataFieldDescriptor *StaticsDescriptors) { assert(OW && "ObjWriter is null"); return OW->GetCompleteClassTypeIndex(ClassDescriptor, ClassFieldsDescriptor, - FieldsDescriptors); + FieldsDescriptors, StaticsDescriptors); } DLL_EXPORT unsigned GetArrayTypeIndex(ObjectWriter *OW, |