Make debug info of HLSL vectors more user friendly (#2018)
The clang type we generate for HLSL vectors contains a single field h of type DependentSizedExtVectorType, which shows up as an int[4] in DWARF. This change specifically emits debug info for x, y, z and w fields instead. With this change, we also stop emitting a vector member for operator[], whose implementation was marked "external" so I don't think it'll have any impact.
This commit is contained in:
Родитель
8275b8103c
Коммит
e487566946
|
@ -1023,6 +1023,34 @@ void CGDebugInfo::CollectRecordFields(
|
|||
}
|
||||
}
|
||||
|
||||
// HLSL Change Begins
|
||||
bool CGDebugInfo::TryCollectHLSLRecordElements(const RecordType *Ty,
|
||||
llvm::DICompositeType *DITy,
|
||||
SmallVectorImpl<llvm::Metadata *> &Elements) {
|
||||
QualType QualTy(Ty, 0);
|
||||
if (hlsl::IsHLSLVecType(QualTy)) {
|
||||
// The HLSL vector type is defined as containing a field 'h' of
|
||||
// extended vector type, which is represented as an array in DWARF.
|
||||
// However, we logically represent it as one field per component.
|
||||
QualType ElemQualTy = hlsl::GetHLSLVecElementType(QualTy);
|
||||
unsigned VecSize = hlsl::GetHLSLVecSize(QualTy);
|
||||
unsigned ElemSizeInBits = CGM.getContext().getTypeSize(ElemQualTy);
|
||||
for (unsigned ElemIdx = 0; ElemIdx < VecSize; ++ElemIdx) {
|
||||
StringRef FieldName = StringRef("xyzw" + ElemIdx, 1);
|
||||
unsigned OffsetInBits = ElemSizeInBits * ElemIdx;
|
||||
llvm::DIType *FieldType = createFieldType(FieldName, ElemQualTy, 0,
|
||||
SourceLocation(), AccessSpecifier::AS_public, OffsetInBits,
|
||||
/* tunit */ nullptr, DITy, Ty->getDecl());
|
||||
Elements.emplace_back(FieldType);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// HLSL Chage Ends
|
||||
|
||||
llvm::DISubroutineType *
|
||||
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
|
||||
llvm::DIFile *Unit) {
|
||||
|
@ -1564,20 +1592,24 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
|
|||
SmallVector<llvm::Metadata *, 16> EltTys;
|
||||
// what about nested types?
|
||||
|
||||
// Note: The split of CXXDecl information here is intentional, the
|
||||
// gdb tests will depend on a certain ordering at printout. The debug
|
||||
// information offsets are still correct if we merge them all together
|
||||
// though.
|
||||
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
|
||||
if (CXXDecl) {
|
||||
CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
|
||||
CollectVTableInfo(CXXDecl, DefUnit, EltTys);
|
||||
}
|
||||
if (!TryCollectHLSLRecordElements(Ty, FwdDecl, EltTys)) { // HLSL Change
|
||||
|
||||
// Collect data fields (including static variables and any initializers).
|
||||
CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
|
||||
if (CXXDecl)
|
||||
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
|
||||
// Note: The split of CXXDecl information here is intentional, the
|
||||
// gdb tests will depend on a certain ordering at printout. The debug
|
||||
// information offsets are still correct if we merge them all together
|
||||
// though.
|
||||
const CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
|
||||
if (CXXDecl) {
|
||||
CollectCXXBases(CXXDecl, DefUnit, EltTys, FwdDecl);
|
||||
CollectVTableInfo(CXXDecl, DefUnit, EltTys);
|
||||
}
|
||||
|
||||
// Collect data fields (including static variables and any initializers).
|
||||
CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
|
||||
if (CXXDecl)
|
||||
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
|
||||
|
||||
} // HLSL Change
|
||||
|
||||
LexicalBlockStack.pop_back();
|
||||
RegionMap.erase(Ty->getDecl());
|
||||
|
|
|
@ -255,6 +255,13 @@ class CGDebugInfo {
|
|||
/// Create a new lexical block node and push it on the stack.
|
||||
void CreateLexicalBlock(SourceLocation Loc);
|
||||
|
||||
// HLSL Change Begins
|
||||
private:
|
||||
bool TryCollectHLSLRecordElements(const RecordType *Ty,
|
||||
llvm::DICompositeType *DITy,
|
||||
SmallVectorImpl<llvm::Metadata *> &Elements);
|
||||
// HLSL Change Ends
|
||||
|
||||
public:
|
||||
CGDebugInfo(CodeGenModule &CGM);
|
||||
~CGDebugInfo();
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: %dxc -T vs_6_0 -E main -Od -Zi %s | FileCheck %s
|
||||
|
||||
// Test that the debug info for HLSL vectors exposes per-component fields.
|
||||
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "int2"
|
||||
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "vector<int, 2>", {{.*}}, size: 64, align: 32
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 32, align: 32
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "y", {{.*}}, size: 32, align: 32, offset: 32
|
||||
int2 main(int2 v : IN) : OUT { return v; }
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: %dxc -T vs_6_0 -E main -Od -Zi %s | FileCheck %s
|
||||
|
||||
// Test that the debug info for HLSL bool vectors exposes per-component fields
|
||||
// in the memory representation of bools (32-bits)
|
||||
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "bool2"
|
||||
// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "vector<bool, 2>", {{.*}}, size: 64, align: 32
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x", {{.*}}, size: 32, align: 32
|
||||
// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "y", {{.*}}, size: 32, align: 32, offset: 32
|
||||
bool2 main(bool2 v : IN) : OUT { return v; }
|
Загрузка…
Ссылка в новой задаче