Skip to content

Commit 0a87c93

Browse files
author
git apple-llvm automerger
committed
Merge commit 'b0bf48d44e55' from llvm.org/main into next
2 parents 608ffbc + b0bf48d commit 0a87c93

File tree

4 files changed

+135
-10
lines changed

4 files changed

+135
-10
lines changed

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,9 @@ namespace llvm {
394394
/// \param OffsetInBits Member offset.
395395
/// \param Flags Flags to encode member attribute, e.g. private
396396
/// \param Discriminant The discriminant for this branch; null for
397-
/// the default branch
397+
/// the default branch. This may be a
398+
/// ConstantDataArray if the variant applies
399+
/// for multiple discriminants.
398400
/// \param Ty Parent type.
399401
DIDerivedType *createVariantMemberType(DIScope *Scope, StringRef Name,
400402
DIFile *File, unsigned LineNo,

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ void DwarfUnit::addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
275275
addAttribute(Die, Attribute, *Form, DIEInteger(Integer));
276276
}
277277

278-
void DwarfUnit::addSInt(DIELoc &Die, std::optional<dwarf::Form> Form,
278+
void DwarfUnit::addSInt(DIEValueList &Die, std::optional<dwarf::Form> Form,
279279
int64_t Integer) {
280280
addSInt(Die, (dwarf::Attribute)0, Form, Integer);
281281
}
@@ -962,6 +962,43 @@ void DwarfUnit::addAnnotation(DIE &Buffer, DINodeArray Annotations) {
962962
}
963963
}
964964

965+
void DwarfUnit::addDiscriminant(DIE &Variant, Constant *Discriminant,
966+
bool IsUnsigned) {
967+
if (const auto *CI = dyn_cast_or_null<ConstantInt>(Discriminant)) {
968+
addInt(Variant, dwarf::DW_AT_discr_value, CI->getValue(), IsUnsigned);
969+
} else if (const auto *CA =
970+
dyn_cast_or_null<ConstantDataArray>(Discriminant)) {
971+
// Must have an even number of operands.
972+
unsigned NElems = CA->getNumElements();
973+
if (NElems % 2 != 0) {
974+
return;
975+
}
976+
977+
DIEBlock *Block = new (DIEValueAllocator) DIEBlock;
978+
979+
auto AddInt = [&](const APInt &Val) {
980+
if (IsUnsigned)
981+
addUInt(*Block, dwarf::DW_FORM_udata, Val.getZExtValue());
982+
else
983+
addSInt(*Block, dwarf::DW_FORM_sdata, Val.getSExtValue());
984+
};
985+
986+
for (unsigned I = 0; I < NElems; I += 2) {
987+
APInt LV = CA->getElementAsAPInt(I);
988+
APInt HV = CA->getElementAsAPInt(I + 1);
989+
if (LV == HV) {
990+
addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_DSC_label);
991+
AddInt(LV);
992+
} else {
993+
addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_DSC_range);
994+
AddInt(LV);
995+
AddInt(HV);
996+
}
997+
}
998+
addBlock(Variant, dwarf::DW_AT_discr_list, Block);
999+
}
1000+
}
1001+
9651002
void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
9661003
// Add name if not anonymous or intermediate type.
9671004
StringRef Name = CTy->getName();
@@ -990,8 +1027,17 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
9901027
// If the variant part has a discriminant, the discriminant is
9911028
// represented by a separate debugging information entry which is
9921029
// a child of the variant part entry.
993-
DIE &DiscMember = constructMemberDIE(Buffer, Discriminator);
994-
addDIEEntry(Buffer, dwarf::DW_AT_discr, DiscMember);
1030+
// However, for a language like Ada, this yields a weird
1031+
// result: a discriminant field would have to be emitted
1032+
// multiple times, once per variant part. Instead, this DWARF
1033+
// restriction was lifted for DWARF 6 (see
1034+
// https://dwarfstd.org/issues/180123.1.html) and so we allow
1035+
// this here.
1036+
DIE *DiscDIE = getDIE(Discriminator);
1037+
if (DiscDIE == nullptr) {
1038+
DiscDIE = &constructMemberDIE(Buffer, Discriminator);
1039+
}
1040+
addDIEEntry(Buffer, dwarf::DW_AT_discr, *DiscDIE);
9951041
}
9961042
}
9971043

@@ -1017,10 +1063,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
10171063
// When emitting a variant part, wrap each member in
10181064
// DW_TAG_variant.
10191065
DIE &Variant = createAndAddDIE(dwarf::DW_TAG_variant, Buffer);
1020-
if (const ConstantInt *CI =
1021-
dyn_cast_or_null<ConstantInt>(DDTy->getDiscriminantValue())) {
1022-
addInt(Variant, dwarf::DW_AT_discr_value, CI->getValue(),
1023-
DD->isUnsignedDIType(Discriminator->getBaseType()));
1066+
if (Constant *CI = DDTy->getDiscriminantValue()) {
1067+
addDiscriminant(Variant, CI,
1068+
DD->isUnsignedDIType(Discriminator->getBaseType()));
10241069
}
10251070
constructMemberDIE(Variant, DDTy);
10261071
} else {
@@ -1759,7 +1804,7 @@ void DwarfUnit::constructContainingTypeDIEs() {
17591804
}
17601805

17611806
DIE &DwarfUnit::constructMemberDIE(DIE &Buffer, const DIDerivedType *DT) {
1762-
DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer);
1807+
DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer, DT);
17631808
StringRef Name = DT->getName();
17641809
if (!Name.empty())
17651810
addString(MemberDie, dwarf::DW_AT_name, Name);

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ class DwarfUnit : public DIEUnit {
165165
void addSInt(DIEValueList &Die, dwarf::Attribute Attribute,
166166
std::optional<dwarf::Form> Form, int64_t Integer);
167167

168-
void addSInt(DIELoc &Die, std::optional<dwarf::Form> Form, int64_t Integer);
168+
void addSInt(DIEValueList &Die, std::optional<dwarf::Form> Form,
169+
int64_t Integer);
169170

170171
/// Add an integer attribute data and value; value may be any width.
171172
void addInt(DIE &Die, dwarf::Attribute Attribute, const APInt &Integer,
@@ -347,6 +348,9 @@ class DwarfUnit : public DIEUnit {
347348
/// form.
348349
void addIntAsBlock(DIE &Die, dwarf::Attribute Attribute, const APInt &Val);
349350

351+
// Add discriminant constants to a DW_TAG_variant DIE.
352+
void addDiscriminant(DIE &Variant, Constant *Discriminant, bool IsUnsigned);
353+
350354
void constructTypeDIE(DIE &Buffer, const DIBasicType *BTy);
351355
void constructTypeDIE(DIE &Buffer, const DIFixedPointType *BTy);
352356
void constructTypeDIE(DIE &Buffer, const DIStringType *BTy);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
; RUN: %llc_dwarf -O0 -filetype=obj < %s > %t
2+
; RUN: llvm-dwarfdump -v -debug-info %t | FileCheck %s
3+
4+
; Check for a variant part that has two members, where one uses a list
5+
; of discriminants, and where both refer to a DIE that is not a child
6+
; of the variant.
7+
8+
; CHECK: DW_AT_name [DW_FORM_strp] ({{.*}} = "Discr")
9+
; CHECK: DW_TAG_variant_part
10+
; CHECK-NOT: TAG
11+
; CHECK: DW_AT_discr [DW_FORM_ref4] (cu + {{0x[0-9a-fA-F]+}} => {[[OFFSET:0x[0-9a-fA-F]+]]})
12+
; CHECK: DW_TAG_variant
13+
; CHECK: DW_AT_discr_list [DW_FORM_block1] (<0x05> 00 17 01 61 6c )
14+
; CHECK: DW_TAG_member
15+
; CHECK: DW_AT_name [DW_FORM_strp] ({{.*}} = "var0")
16+
; CHECK: DW_AT_type
17+
; CHECK: DW_AT_alignment
18+
; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
19+
; CHECK: DW_TAG_variant
20+
; CHECK: DW_AT_discr_value [DW_FORM_data1] (0x4b)
21+
; CHECK: DW_TAG_member
22+
; CHECK: DW_AT_type
23+
; CHECK: DW_AT_alignment
24+
; CHECK: DW_AT_data_member_location [DW_FORM_data1] (0x00)
25+
26+
%F = type { [0 x i8], ptr, [8 x i8] }
27+
%"F::Nope" = type {}
28+
29+
define internal void @_ZN2e34main17h934ff72f9a38d4bbE() unnamed_addr #0 !dbg !5 {
30+
start:
31+
%qq = alloca %F, align 8
32+
call void @llvm.dbg.declare(metadata ptr %qq, metadata !10, metadata !28), !dbg !29
33+
store ptr null, ptr %qq, !dbg !29
34+
ret void, !dbg !30
35+
}
36+
37+
; Function Attrs: nounwind readnone
38+
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
39+
40+
attributes #0 = { nounwind uwtable }
41+
42+
!llvm.module.flags = !{!0, !1}
43+
!llvm.dbg.cu = !{!2}
44+
45+
!0 = !{i32 1, !"PIE Level", i32 2}
46+
!1 = !{i32 2, !"Debug Info Version", i32 3}
47+
!2 = distinct !DICompileUnit(language: DW_LANG_Ada95, file: !3, producer: "gnat-llvm", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4)
48+
!3 = !DIFile(filename: "e3.rs", directory: "/home/tromey/Ada")
49+
!4 = !{}
50+
!5 = distinct !DISubprogram(name: "main", linkageName: "_ZN2e34mainE", scope: !6, file: !3, line: 2, type: !8, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagMainSubprogram, isOptimized: false, unit: !2, templateParams: !4, retainedNodes: !4)
51+
!6 = !DINamespace(name: "e3", scope: null)
52+
!7 = !DIFile(filename: "<unknown>", directory: "")
53+
!8 = !DISubroutineType(types: !9)
54+
!9 = !{null}
55+
!10 = !DILocalVariable(name: "qq", scope: !11, file: !3, line: 3, type: !12, align: 8)
56+
!11 = distinct !DILexicalBlock(scope: !5, file: !3, line: 3, column: 4)
57+
!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "F", scope: !6, file: !7, size: 128, align: 64, elements: !13, identifier: "7ce1efff6b82281ab9ceb730566e7e20")
58+
!13 = !{!14, !15}
59+
!14 = !DIDerivedType(tag: DW_TAG_member, name: "Discr", scope: !12, file: !7, baseType: !27, size: 64, align: 64)
60+
!15 = !DICompositeType(tag: DW_TAG_variant_part, scope: !12, file: !7, size: 128, align: 64, elements: !16, identifier: "7ce1efff6b82281ab9ceb730566e7e20", discriminator: !14)
61+
!16 = !{!17, !24}
62+
!17 = !DIDerivedType(tag: DW_TAG_member, name: "var0", scope: !15, file: !7, baseType: !18, size: 128, align: 64, extraData: [4 x i32] [i32 23, i32 23, i32 97, i32 108])
63+
!18 = !DICompositeType(tag: DW_TAG_structure_type, name: "Yep", scope: !12, file: !7, size: 128, align: 64, elements: !19, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Yep")
64+
!19 = !{!20, !22}
65+
!20 = !DIDerivedType(tag: DW_TAG_member, name: "var1", scope: !18, file: !7, baseType: !21, size: 8, align: 8, offset: 64)
66+
!21 = !DIBasicType(name: "u8", size: 8, encoding: DW_ATE_unsigned)
67+
!22 = !DIDerivedType(tag: DW_TAG_member, name: "var2", scope: !18, file: !7, baseType: !23, size: 64, align: 64)
68+
!23 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "&u8", baseType: !21, size: 64, align: 64)
69+
!24 = !DIDerivedType(tag: DW_TAG_member, scope: !15, file: !7, baseType: !25, size: 128, align: 64, extraData: i32 75)
70+
!25 = !DICompositeType(tag: DW_TAG_structure_type, name: "Nope", scope: !12, file: !7, size: 128, align: 64, elements: !4, identifier: "7ce1efff6b82281ab9ceb730566e7e20::Nope")
71+
!27 = !DIBasicType(name: "u64", size: 64, encoding: DW_ATE_unsigned)
72+
!28 = !DIExpression()
73+
!29 = !DILocation(line: 3, scope: !11)
74+
!30 = !DILocation(line: 4, scope: !5)

0 commit comments

Comments
 (0)