|
@@ -213,85 +213,91 @@ private:
|
|
std::vector<FragmentSizeAndOffset> m_fragmentLocations;
|
|
std::vector<FragmentSizeAndOffset> m_fragmentLocations;
|
|
unsigned m_currentFragment = 0;
|
|
unsigned m_currentFragment = 0;
|
|
void CompositeTypeFragmentIterator::DetermineStructMemberSizesAndOffsets(
|
|
void CompositeTypeFragmentIterator::DetermineStructMemberSizesAndOffsets(
|
|
- llvm::DIType const*);
|
|
|
|
|
|
+ llvm::DIType const*, uint64_t BaseOffset);
|
|
};
|
|
};
|
|
|
|
|
|
-
|
|
|
|
-void CompositeTypeFragmentIterator::DetermineStructMemberSizesAndOffsets(llvm::DIType const*diType)
|
|
|
|
|
|
+unsigned SizeIfBaseType(llvm::DIType const* diType)
|
|
{
|
|
{
|
|
- auto AddANewFragment = [=](llvm::DIType const * type)
|
|
|
|
|
|
+ if (auto* BT = llvm::dyn_cast<llvm::DIBasicType>(diType))
|
|
{
|
|
{
|
|
- unsigned size = static_cast<unsigned>(type->getSizeInBits());
|
|
|
|
- if (m_fragmentLocations.empty())
|
|
|
|
- {
|
|
|
|
- m_fragmentLocations.push_back({ size, 0 });
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- unsigned offset = m_fragmentLocations.back().Offset + m_fragmentLocations.back().Size;
|
|
|
|
- m_fragmentLocations.push_back({ size, offset });
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
|
|
+ return BT->getSizeInBits();
|
|
|
|
+ }
|
|
|
|
+ if (auto* DT = llvm::dyn_cast<llvm::DIDerivedType>(diType))
|
|
|
|
+ {
|
|
|
|
+ const llvm::DITypeIdentifierMap EmptyMap;
|
|
|
|
+ return SizeIfBaseType(DT->getBaseType().resolve(EmptyMap));
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
|
|
- if (auto* BT = llvm::dyn_cast<llvm::DIBasicType>(diType))
|
|
|
|
|
|
+void CompositeTypeFragmentIterator::DetermineStructMemberSizesAndOffsets(llvm::DIType const*diType, uint64_t BaseOffset)
|
|
|
|
+{
|
|
|
|
+ if (diType->getTag() == llvm::dwarf::DW_TAG_member)
|
|
{
|
|
{
|
|
- AddANewFragment(BT);
|
|
|
|
|
|
+ BaseOffset += diType->getOffsetInBits();
|
|
}
|
|
}
|
|
- else if (auto* CT = llvm::dyn_cast<llvm::DICompositeType>(diType))
|
|
|
|
|
|
+ unsigned MemberSize = SizeIfBaseType(diType);
|
|
|
|
+ if (MemberSize != 0)
|
|
{
|
|
{
|
|
- switch (diType->getTag())
|
|
|
|
- {
|
|
|
|
- case llvm::dwarf::DW_TAG_array_type :
|
|
|
|
|
|
+ m_fragmentLocations.push_back({ MemberSize, static_cast<unsigned>(BaseOffset) });
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (auto* CT = llvm::dyn_cast<llvm::DICompositeType>(diType))
|
|
{
|
|
{
|
|
- llvm::DINodeArray elements = CT->getElements();
|
|
|
|
- unsigned arraySize = 1;
|
|
|
|
- for (auto const& node : elements)
|
|
|
|
|
|
+
|
|
|
|
+ switch (diType->getTag())
|
|
|
|
+ {
|
|
|
|
+ case llvm::dwarf::DW_TAG_array_type:
|
|
{
|
|
{
|
|
- if (llvm::DISubrange* SR = llvm::dyn_cast<llvm::DISubrange>(node))
|
|
|
|
|
|
+ llvm::DINodeArray elements = CT->getElements();
|
|
|
|
+ unsigned arraySize = 1;
|
|
|
|
+ for (auto const& node : elements)
|
|
{
|
|
{
|
|
- arraySize *= SR->getCount();
|
|
|
|
|
|
+ if (llvm::DISubrange* SR = llvm::dyn_cast<llvm::DISubrange>(node))
|
|
|
|
+ {
|
|
|
|
+ arraySize *= SR->getCount();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (arraySize != 0)
|
|
|
|
+ {
|
|
|
|
+ const llvm::DITypeIdentifierMap EmptyMap;
|
|
|
|
+ llvm::DIType* BT = CT->getBaseType().resolve(EmptyMap);
|
|
|
|
+ unsigned elementSize = static_cast<unsigned>(CT->getSizeInBits()) / arraySize;
|
|
|
|
+ for (unsigned i = 0; i < arraySize; ++i) {
|
|
|
|
+ DetermineStructMemberSizesAndOffsets(BT, BaseOffset + i * elementSize);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- const llvm::DITypeIdentifierMap EmptyMap;
|
|
|
|
- llvm::DIType *BT = CT->getBaseType().resolve(EmptyMap);
|
|
|
|
- for (unsigned i = 0; i < arraySize; ++i) {
|
|
|
|
- DetermineStructMemberSizesAndOffsets(BT);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
break;
|
|
break;
|
|
- case llvm::dwarf::DW_TAG_class_type:
|
|
|
|
- case llvm::dwarf::DW_TAG_structure_type:
|
|
|
|
- for (auto const& node : CT->getElements())
|
|
|
|
- {
|
|
|
|
- if (llvm::DIType* subType = llvm::dyn_cast<llvm::DIType>(node))
|
|
|
|
|
|
+ case llvm::dwarf::DW_TAG_class_type:
|
|
|
|
+ case llvm::dwarf::DW_TAG_structure_type:
|
|
|
|
+ for (auto const& node : CT->getElements())
|
|
{
|
|
{
|
|
- DetermineStructMemberSizesAndOffsets(subType);
|
|
|
|
|
|
+ if (llvm::DIType* subType = llvm::dyn_cast<llvm::DIType>(node))
|
|
|
|
+ {
|
|
|
|
+ DetermineStructMemberSizesAndOffsets(subType, BaseOffset /*TODO: plus member offset*/);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ diType->dump();
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- diType->dump();
|
|
|
|
- break;
|
|
|
|
}
|
|
}
|
|
- }
|
|
|
|
- else if (auto *DT = llvm::dyn_cast<llvm::DIDerivedType>(diType))
|
|
|
|
- {
|
|
|
|
- const llvm::DITypeIdentifierMap EmptyMap;
|
|
|
|
- llvm::DIType *BT = DT->getBaseType().resolve(EmptyMap);
|
|
|
|
- DetermineStructMemberSizesAndOffsets(BT);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- assert(!"Unhandled DIType");
|
|
|
|
- throw hlsl::Exception(E_FAIL, "Unhandled DIType");
|
|
|
|
|
|
+ else if (auto* DT = llvm::dyn_cast<llvm::DIDerivedType>(diType))
|
|
|
|
+ {
|
|
|
|
+ const llvm::DITypeIdentifierMap EmptyMap;
|
|
|
|
+ llvm::DIType* BT = DT->getBaseType().resolve(EmptyMap);
|
|
|
|
+ DetermineStructMemberSizesAndOffsets(BT, BaseOffset);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
CompositeTypeFragmentIterator::CompositeTypeFragmentIterator(
|
|
CompositeTypeFragmentIterator::CompositeTypeFragmentIterator(
|
|
llvm::DICompositeType* CT)
|
|
llvm::DICompositeType* CT)
|
|
{
|
|
{
|
|
- DetermineStructMemberSizesAndOffsets(CT);
|
|
|
|
|
|
+ DetermineStructMemberSizesAndOffsets(CT, 0);
|
|
}
|
|
}
|
|
|
|
|
|
unsigned CompositeTypeFragmentIterator::SizeInBits(unsigned Index) const
|
|
unsigned CompositeTypeFragmentIterator::SizeInBits(unsigned Index) const
|