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 *
|
llvm::DISubroutineType *
|
||||||
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
|
CGDebugInfo::getOrCreateMethodType(const CXXMethodDecl *Method,
|
||||||
llvm::DIFile *Unit) {
|
llvm::DIFile *Unit) {
|
||||||
|
@ -1564,20 +1592,24 @@ llvm::DIType *CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
|
||||||
SmallVector<llvm::Metadata *, 16> EltTys;
|
SmallVector<llvm::Metadata *, 16> EltTys;
|
||||||
// what about nested types?
|
// what about nested types?
|
||||||
|
|
||||||
// Note: The split of CXXDecl information here is intentional, the
|
if (!TryCollectHLSLRecordElements(Ty, FwdDecl, EltTys)) { // HLSL Change
|
||||||
// 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).
|
// Note: The split of CXXDecl information here is intentional, the
|
||||||
CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
|
// gdb tests will depend on a certain ordering at printout. The debug
|
||||||
if (CXXDecl)
|
// information offsets are still correct if we merge them all together
|
||||||
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
|
// 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();
|
LexicalBlockStack.pop_back();
|
||||||
RegionMap.erase(Ty->getDecl());
|
RegionMap.erase(Ty->getDecl());
|
||||||
|
|
|
@ -255,6 +255,13 @@ class CGDebugInfo {
|
||||||
/// Create a new lexical block node and push it on the stack.
|
/// Create a new lexical block node and push it on the stack.
|
||||||
void CreateLexicalBlock(SourceLocation Loc);
|
void CreateLexicalBlock(SourceLocation Loc);
|
||||||
|
|
||||||
|
// HLSL Change Begins
|
||||||
|
private:
|
||||||
|
bool TryCollectHLSLRecordElements(const RecordType *Ty,
|
||||||
|
llvm::DICompositeType *DITy,
|
||||||
|
SmallVectorImpl<llvm::Metadata *> &Elements);
|
||||||
|
// HLSL Change Ends
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CGDebugInfo(CodeGenModule &CGM);
|
CGDebugInfo(CodeGenModule &CGM);
|
||||||
~CGDebugInfo();
|
~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; }
|
Загрузка…
Ссылка в новой задаче