llvm.org GIT mirror llvm / 0b268d6
Revert "[DebugInfo] Improvements to representation of enumeration types (PR36168)" Revert commit r324489, it broke LLDB tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@324511 91177308-0d34-0410-b5e6-96231b3b80d8 Momchil Velikov 2 years ago
16 changed file(s) with 57 addition(s) and 398 deletion(s). Raw diff Collapse all Expand all
278278 METADATA_ATTACHMENT = 11, // [m x [value, [n x [id, mdnode]]]
279279 METADATA_GENERIC_DEBUG = 12, // [distinct, tag, vers, header, n x md num]
280280 METADATA_SUBRANGE = 13, // [distinct, count, lo]
281 METADATA_ENUMERATOR = 14, // [isUnsigned|distinct, value, name]
281 METADATA_ENUMERATOR = 14, // [distinct, value, name]
282282 METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc]
283283 METADATA_FILE = 16, // [distinct, filename, directory, checksumkind, checksum]
284284 METADATA_DERIVED_TYPE = 17, // [distinct, ...]
165165 DIFile *File);
166166
167167 /// Create a single enumerator value.
168 DIEnumerator *createEnumerator(StringRef Name, int64_t Val, bool IsUnsigned = false);
168 DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
169169
170170 /// Create a DWARF unspecified type.
171171 DIBasicType *createUnspecifiedType(StringRef Name);
486486 /// \param Elements Enumeration elements.
487487 /// \param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
488488 /// \param UniqueIdentifier A unique identifier for the enum.
489 /// \param IsFixed Boolean flag indicate if this is C++11/ObjC fixed enum.
490489 DICompositeType *createEnumerationType(
491490 DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
492491 uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,
493 DIType *UnderlyingType, StringRef UniqueIdentifier = "", bool IsFixed = false);
492 DIType *UnderlyingType, StringRef UniqueIdentifier = "");
494493
495494 /// Create subroutine type.
496495 /// \param ParameterTypes An array of subroutine parameter types. This
4444 HANDLE_DI_FLAG((1 << 21), MainSubprogram)
4545 HANDLE_DI_FLAG((1 << 22), TypePassByValue)
4646 HANDLE_DI_FLAG((1 << 23), TypePassByReference)
47 HANDLE_DI_FLAG((1 << 24), FixedEnum)
4847
4948 // To avoid needing a dedicated value for IndirectVirtualBase, we use
5049 // the bitwise or of Virtual and FwdDecl, which does not otherwise
5453 #ifdef DI_FLAG_LARGEST_NEEDED
5554 // intended to be used with ADT/BitmaskEnum.h
5655 // NOTE: always must be equal to largest flag, check this when adding new flag
57 HANDLE_DI_FLAG((1 << 24), Largest)
56 HANDLE_DI_FLAG((1 << 23), Largest)
5857 #undef DI_FLAG_LARGEST_NEEDED
5958 #endif
6059
395395 friend class MDNode;
396396
397397 int64_t Value;
398
398399 DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
399 bool IsUnsigned, ArrayRef Ops)
400 ArrayRef Ops)
400401 : DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
401 Value(Value) {
402 SubclassData32 = IsUnsigned;
403 }
402 Value(Value) {}
404403 ~DIEnumerator() = default;
405404
406405 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
407 bool IsUnsigned, StringRef Name,
408 StorageType Storage, bool ShouldCreate = true) {
409 return getImpl(Context, Value, IsUnsigned,
410 getCanonicalMDString(Context, Name), Storage, ShouldCreate);
406 StringRef Name, StorageType Storage,
407 bool ShouldCreate = true) {
408 return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
409 ShouldCreate);
411410 }
412411 static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
413 bool IsUnsigned, MDString *Name,
414 StorageType Storage, bool ShouldCreate = true);
412 MDString *Name, StorageType Storage,
413 bool ShouldCreate = true);
415414
416415 TempDIEnumerator cloneImpl() const {
417 return getTemporary(getContext(), getValue(), isUnsigned(), getName());
418 }
419
420 public:
421 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name),
422 (Value, IsUnsigned, Name))
423 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name),
424 (Value, IsUnsigned, Name))
416 return getTemporary(getContext(), getValue(), getName());
417 }
418
419 public:
420 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, StringRef Name),
421 (Value, Name))
422 DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, MDString *Name),
423 (Value, Name))
425424
426425 TempDIEnumerator clone() const { return cloneImpl(); }
427426
428427 int64_t getValue() const { return Value; }
429 bool isUnsigned() const { return SubclassData32; }
430428 StringRef getName() const { return getStringOperand(0); }
431429
432430 MDString *getRawName() const { return getOperandAs(0); }
36353635 }
36363636 };
36373637
3638 struct MDSignedOrUnsignedField
3639 : MDEitherFieldImpl {
3640 MDSignedOrUnsignedField() : ImplTy(MDSignedField(0), MDUnsignedField(0)) {}
3641
3642 bool isMDSignedField() const { return WhatIs == IsTypeA; }
3643 bool isMDUnsignedField() const { return WhatIs == IsTypeB; }
3644 int64_t getMDSignedValue() const {
3645 assert(isMDSignedField() && "Wrong field type");
3646 return A.Val;
3647 }
3648 uint64_t getMDUnsignedValue() const {
3649 assert(isMDUnsignedField() && "Wrong field type");
3650 return B.Val;
3651 }
3652 };
3653
36543638 } // end anonymous namespace
36553639
36563640 namespace llvm {
39253909 }
39263910
39273911 return true;
3928 }
3929
3930 template <>
3931 bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
3932 MDSignedOrUnsignedField &Result) {
3933 if (Lex.getKind() != lltok::APSInt)
3934 return false;
3935
3936 if (Lex.getAPSIntVal().isSigned()) {
3937 MDSignedField Res = Result.A;
3938 if (ParseMDField(Loc, Name, Res))
3939 return true;
3940 Result.assign(Res);
3941 return false;
3942 }
3943
3944 MDUnsignedField Res = Result.B;
3945 if (ParseMDField(Loc, Name, Res))
3946 return true;
3947 Result.assign(Res);
3948 return false;
39493912 }
39503913
39513914 template <>
41134076 }
41144077
41154078 /// ParseDIEnumerator:
4116 /// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind")
4079 /// ::= !DIEnumerator(value: 30, name: "SomeKind")
41174080 bool LLParser::ParseDIEnumerator(MDNode *&Result, bool IsDistinct) {
41184081 #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
41194082 REQUIRED(name, MDStringField, ); \
4120 REQUIRED(value, MDSignedOrUnsignedField, ); \
4121 OPTIONAL(isUnsigned, MDBoolField, (false));
4083 REQUIRED(value, MDSignedField, );
41224084 PARSE_MD_FIELDS();
41234085 #undef VISIT_MD_FIELDS
41244086
4125 if (isUnsigned.Val && value.isMDSignedField())
4126 return TokError("unsigned enumerator with negative value");
4127
4128 int64_t Value = value.isMDSignedField()
4129 ? value.getMDSignedValue()
4130 : static_cast(value.getMDUnsignedValue());
4131 Result =
4132 GET_OR_DISTINCT(DIEnumerator, (Context, Value, isUnsigned.Val, name.Val));
4133
4087 Result = GET_OR_DISTINCT(DIEnumerator, (Context, value.Val, name.Val));
41344088 return false;
41354089 }
41364090
11991199 if (Record.size() != 3)
12001200 return error("Invalid record");
12011201
1202 IsDistinct = Record[0] & 1;
1203 bool IsUnsigned = Record[0] & 2;
1202 IsDistinct = Record[0];
12041203 MetadataList.assignValue(
12051204 GET_OR_DISTINCT(DIEnumerator, (Context, unrotateSign(Record[1]),
1206 IsUnsigned, getMDString(Record[2]))),
1205 getMDString(Record[2]))),
12071206 NextMetadataNo);
12081207 NextMetadataNo++;
12091208 break;
14561456 void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N,
14571457 SmallVectorImpl &Record,
14581458 unsigned Abbrev) {
1459 Record.push_back((N->isUnsigned() << 1) | N->isDistinct());
1459 Record.push_back(N->isDistinct());
14601460 Record.push_back(rotateSign(N->getValue()));
14611461 Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
14621462
14261426 }
14271427
14281428 void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
1429 const DIType *DTy = resolve(CTy->getBaseType());
1430 bool IsUnsigned = DTy && isUnsignedDIType(DD, DTy);
1431 if (DTy && DD->getDwarfVersion() >= 3)
1432 addType(Buffer, DTy);
1433 if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagFixedEnum)) {
1434 assert(DTy);
1435 addFlag(Buffer, dwarf::DW_AT_enum_class);
1436 }
1437
14381429 DINodeArray Elements = CTy->getElements();
14391430
14401431 // Add enumerators to enumeration type.
14441435 DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
14451436 StringRef Name = Enum->getName();
14461437 addString(Enumerator, dwarf::DW_AT_name, Name);
1447 auto Value = static_cast(Enum->getValue());
1448 addConstantValue(Enumerator, IsUnsigned, Value);
1438 int64_t Value = Enum->getValue();
1439 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata,
1440 Value);
14491441 }
1442 }
1443 const DIType *DTy = resolve(CTy->getBaseType());
1444 if (DTy) {
1445 addType(Buffer, DTy);
1446 addFlag(Buffer, dwarf::DW_AT_enum_class);
14501447 }
14511448 }
14521449
16281628 Out << "!DIEnumerator(";
16291629 MDFieldPrinter Printer(Out);
16301630 Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
1631 if (N->isUnsigned()) {
1632 auto Value = static_cast(N->getValue());
1633 Printer.printInt("value", Value, /* ShouldSkipZero */ false);
1634 Printer.printBool("isUnsigned", true);
1635 } else {
1636 Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
1637 }
1631 Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
16381632 Out << ")";
16391633 }
16401634
232232 return MF;
233233 }
234234
235 DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val,
236 bool IsUnsigned) {
235 DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val) {
237236 assert(!Name.empty() && "Unable to create enumerator without name");
238 return DIEnumerator::get(VMContext, Val, IsUnsigned, Name);
237 return DIEnumerator::get(VMContext, Val, Name);
239238 }
240239
241240 DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) {
492491 DICompositeType *DIBuilder::createEnumerationType(
493492 DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
494493 uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,
495 DIType *UnderlyingType, StringRef UniqueIdentifier, bool IsFixed) {
494 DIType *UnderlyingType, StringRef UniqueIdentifier) {
496495 auto *CTy = DICompositeType::get(
497496 VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber,
498497 getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0,
499 IsFixed ? DINode::FlagFixedEnum : DINode::FlagZero, Elements, 0, nullptr,
500 nullptr, UniqueIdentifier);
498 DINode::FlagZero, Elements, 0, nullptr, nullptr, UniqueIdentifier);
501499 AllEnumTypes.push_back(CTy);
502500 trackIfUnresolved(CTy);
503501 return CTy;
262262 }
263263
264264 DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, int64_t Value,
265 bool IsUnsigned, MDString *Name,
266 StorageType Storage, bool ShouldCreate) {
267 assert(isCanonical(Name) && "Expected canonical MDString");
268 DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
265 MDString *Name, StorageType Storage,
266 bool ShouldCreate) {
267 assert(isCanonical(Name) && "Expected canonical MDString");
268 DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, Name));
269269 Metadata *Ops[] = {Name};
270 DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
270 DEFINE_GETIMPL_STORE(DIEnumerator, (Value), Ops);
271271 }
272272
273273 DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
353353 template <> struct MDNodeKeyImpl {
354354 int64_t Value;
355355 MDString *Name;
356 bool IsUnsigned;
357
358 MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
359 : Value(Value), Name(Name), IsUnsigned(IsUnsigned) {}
356
357 MDNodeKeyImpl(int64_t Value, MDString *Name) : Value(Value), Name(Name) {}
360358 MDNodeKeyImpl(const DIEnumerator *N)
361 : Value(N->getValue()), Name(N->getRawName()),
362 IsUnsigned(N->isUnsigned()) {}
359 : Value(N->getValue()), Name(N->getRawName()) {}
363360
364361 bool isKeyOf(const DIEnumerator *RHS) const {
365 return Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
366 Name == RHS->getRawName();
362 return Value == RHS->getValue() && Name == RHS->getRawName();
367363 }
368364
369365 unsigned getHashValue() const { return hash_combine(Value, Name); }
+0
-85
test/Assembler/DIEnumerator.ll less more
None ; Round-trip test for the following program:
1 ; ```
2 ; enum E0 { A0 = -2147483648, B0 = 2147483647 } x0;
3 ; enum E1 : signed int { A1 = -2147483648, B1 = 2147483647 } x1;
4 ; enum E2 : signed long long { A2 = -9223372036854775807LL - 1,
5 ; B2 = 9223372036854775807LL } x2;
6 ; enum E3 : unsigned long long { A3 = 0x8000000000000000ULL } x3;
7 ; ```
8 ; Test FixedEnum flag presence/absence, the underlying integer type and
9 ; enumerator values (signed and unsigned, and extreme cases) all survive through
10 ; the round-trip.
11
12 ; RUN: llvm-as %s -o - | llvm-dis | llvm-as | llvm-dis | FileCheck %s
13
14 @x0 = global i32 0, align 4, !dbg !0
15 @x1 = global i32 0, align 4, !dbg !24
16 @x2 = global i64 0, align 8, !dbg !26
17 @x3 = global i64 0, align 8, !dbg !28
18
19 !llvm.dbg.cu = !{!2}
20 !llvm.module.flags = !{!30, !31, !32}
21 !llvm.ident = !{!33}
22
23 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
24 !1 = distinct !DIGlobalVariable(name: "x0", scope: !2, file: !3, line: 1, type: !5, isLocal: false, isDefinition: true)
25 !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (/data/src/llvm/tools/clang 697b0cb4c2e712a28767c2f7fe50c90bae7255f5) (/data/src/llvm 5ba8dcca7470b5da405bc92b9681b1f36e5d6772)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !23)
26 !3 = !DIFile(filename: "e.cc", directory: "/work/build/clang-dev")
27 !4 = !{!5, !10, !14, !19}
28
29
30 !5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E0", file: !3, line: 1, baseType: !6, size: 32, elements: !7, identifier: "_ZTS2E0")
31 ; CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E0"{{.*}}, baseType: ![[INT:[0-9]+]]
32 ; CHECK-NOT: FixedEnum
33 !6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
34 ; CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
35 !7 = !{!8, !9}
36 !8 = !DIEnumerator(name: "A0", value: -2147483648)
37 !9 = !DIEnumerator(name: "B0", value: 2147483647)
38 ; CHECK: !DIEnumerator(name: "A0", value: -2147483648)
39 ; CHECK: !DIEnumerator(name: "B0", value: 2147483647)
40
41
42 !10 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E1", file: !3, line: 3, baseType: !6, size: 32, flags: DIFlagFixedEnum, elements: !11, identifier: "_ZTS2E1")
43 ; CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E1"{{.*}}, baseType: ![[INT]]
44 ; CHECK-SAME: DIFlagFixedEnum
45 !11 = !{!12, !13}
46 !12 = !DIEnumerator(name: "A1", value: -2147483648)
47 !13 = !DIEnumerator(name: "B1", value: 2147483647)
48 ; CHECK: !DIEnumerator(name: "A1", value: -2147483648)
49 ; CHECK: !DIEnumerator(name: "B1", value: 2147483647)
50
51
52 !14 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E2", file: !3, line: 5, baseType: !15, size: 64, flags: DIFlagFixedEnum, elements: !16, identifier: "_ZTS2E2")
53 ; CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E2"{{.*}}, baseType: ![[LONG:[0-9]+]]
54 ; CHECK-SAME: DIFlagFixedEnum
55 !15 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed)
56 ; CHECK: ![[LONG]] = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed)
57 !16 = !{!17, !18}
58 !17 = !DIEnumerator(name: "A2", value: -9223372036854775808)
59 !18 = !DIEnumerator(name: "B2", value: 9223372036854775807)
60 ; CHECK: !DIEnumerator(name: "A2", value: -9223372036854775808)
61 ; CHECK: !DIEnumerator(name: "B2", value: 9223372036854775807)
62
63
64 !19 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E3", file: !3, line: 7, baseType: !20, size: 64, flags: DIFlagFixedEnum, elements: !21, identifier: "_ZTS2E3")
65 ; CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E3"{{.*}}, baseType: ![[ULONG:[0-9]+]]
66 ; CHECK-SAME: DIFlagFixedEnum
67 !20 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
68 ; CHECK: ![[ULONG]] = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
69 !21 = !{!22}
70 !22 = !DIEnumerator(name: "A3", value: 9223372036854775808, isUnsigned: true)
71 ; CHECK: !DIEnumerator(name: "A3", value: 9223372036854775808, isUnsigned: true)
72
73
74 !23 = !{!0, !24, !26, !28}
75 !24 = !DIGlobalVariableExpression(var: !25, expr: !DIExpression())
76 !25 = distinct !DIGlobalVariable(name: "x1", scope: !2, file: !3, line: 3, type: !10, isLocal: false, isDefinition: true)
77 !26 = !DIGlobalVariableExpression(var: !27, expr: !DIExpression())
78 !27 = distinct !DIGlobalVariable(name: "x2", scope: !2, file: !3, line: 5, type: !14, isLocal: false, isDefinition: true)
79 !28 = !DIGlobalVariableExpression(var: !29, expr: !DIExpression())
80 !29 = distinct !DIGlobalVariable(name: "x3", scope: !2, file: !3, line: 7, type: !19, isLocal: false, isDefinition: true)
81 !30 = !{i32 2, !"Dwarf Version", i32 4}
82 !31 = !{i32 2, !"Debug Info Version", i32 3}
83 !32 = !{i32 1, !"wchar_size", i32 4}
84 !33 = !{!"clang version 7.0.0 (/data/src/llvm/tools/clang 697b0cb4c2e712a28767c2f7fe50c90bae7255f5) (/data/src/llvm 5ba8dcca7470b5da405bc92b9681b1f36e5d6772)"}
+0
-188
test/DebugInfo/Generic/debug-info-enum.ll less more
None ; Test enumeration representation in DWARF debug info:
1 ; * test value representation for each possible underlying integer type
2 ; * test the integer type is as expected
3 ; * test the DW_AT_enum_class attribute is present (resp. absent) as expected.
4
5 ; RUN: llc -debugger-tune=gdb -dwarf-version=4 -filetype=obj -o %t.o < %s
6 ; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DW4
7 ; RUN: llc -debugger-tune=gdb -dwarf-version=2 -filetype=obj -o %t.o < %s
8 ; RUN: llvm-dwarfdump -debug-info %t.o | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DW2
9
10 @x0 = global i8 0, align 1, !dbg !0
11 @x1 = global i8 0, align 1, !dbg !46
12 @x2 = global i16 0, align 2, !dbg !48
13 @x3 = global i16 0, align 2, !dbg !50
14 @x4 = global i32 0, align 4, !dbg !52
15 @x5 = global i32 0, align 4, !dbg !54
16 @x6 = global i64 0, align 8, !dbg !56
17 @x7 = global i64 0, align 8, !dbg !58
18 @x8 = global i32 0, align 4, !dbg !60
19
20 !llvm.dbg.cu = !{!2}
21 !llvm.module.flags = !{!62}
22
23 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
24 !1 = distinct !DIGlobalVariable(name: "x0", scope: !2, file: !3, line: 5, type: !5, isLocal: false, isDefinition: true)
25 !2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 7.0.0 (/data/src/llvm/tools/clang 0c08d9830124a75675348b4eeb47256f3da6693d) (/data/src/llvm cf29510f52faa77b98510cd53276f564d1f4f41f)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !45)
26 !3 = !DIFile(filename: "/data/src/llvm-dev/tools/clang/test/CodeGen/debug-info-enum.cpp", directory: "/work/build/clang-dev")
27 !4 = !{!5, !10, !14, !19, !23, !28, !32, !37, !41}
28
29 ; Test enumeration with a fixed "signed char" underlying type.
30 !5 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E0", file: !3, line: 2, baseType: !6, size: 8, flags: DIFlagFixedEnum, elements: !7, identifier: "_ZTS2E0")
31 !6 = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char)
32 !7 = !{!8, !9}
33 !8 = !DIEnumerator(name: "A0", value: -128)
34 !9 = !DIEnumerator(name: "B0", value: 127)
35 ; CHECK: DW_TAG_enumeration_type
36 ; CHECK-DW2-NOT: DW_AT_type
37 ; CHECK-DW4: DW_AT_type{{.*}}"signed char"
38 ; CHECK-DW4: DW_AT_enum_class (true)
39 ; CHECK: DW_AT_name ("E0")
40 ; CHECK: DW_TAG_enumerator
41 ; CHECK: DW_AT_name ("A0")
42 ; CHECK-NEXT: DW_AT_const_value (-128)
43 ; CHECK: DW_TAG_enumerator
44 ; CHECK: DW_AT_name ("B0")
45 ; CHECK-NEXT: DW_AT_const_value (127)
46
47 ; Test enumeration with a fixed "unsigned char" underlying type.
48 !10 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E1", file: !3, line: 12, baseType: !11, size: 8, flags: DIFlagFixedEnum, elements: !12, identifier: "_ZTS2E1")
49 !11 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char)
50 !12 = !{!13}
51 !13 = !DIEnumerator(name: "A1", value: 255, isUnsigned: true)
52 ; CHECK: DW_TAG_enumeration_type
53 ; CHECK-DW2-NOT: DW_AT_type
54 ; CHECK-DW4: DW_AT_type{{.*}}"unsigned char"
55 ; CHECK-DW4: DW_AT_enum_class (true)
56 ; CHECK: DW_AT_name ("E1")
57 ; CHECK: DW_TAG_enumerator
58 ; CHECK: DW_AT_name ("A1")
59 ; CHECK-NEXT: DW_AT_const_value (255)
60
61 ; Test enumeration with a fixed "short" underlying type.
62 !14 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E2", file: !3, line: 18, baseType: !15, size: 16, flags: DIFlagFixedEnum, elements: !16, identifier: "_ZTS2E2")
63 !15 = !DIBasicType(name: "short", size: 16, encoding: DW_ATE_signed)
64 !16 = !{!17, !18}
65 !17 = !DIEnumerator(name: "A2", value: -32768)
66 !18 = !DIEnumerator(name: "B2", value: 32767)
67 ; CHECK: DW_TAG_enumeration_type
68 ; CHECK-DW2-NOT: DW_AT_type
69 ; CHECK-DW4: DW_AT_type{{.*}} "short"
70 ; CHECK-DW4: DW_AT_enum_class (true)
71 ; CHECK: DW_AT_name ("E2")
72 ; CHECK: DW_TAG_enumerator
73 ; CHECK: DW_AT_name ("A2")
74 ; CHECK-NEXT: DW_AT_const_value (-32768)
75 ; CHECK: DW_TAG_enumerator
76 ; CHECK: DW_AT_name ("B2")
77 ; CHECK-NEXT: DW_AT_const_value (32767)
78
79 ; Test enumeration with a fixed "unsigned short" underlying type.
80 !19 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E3", file: !3, line: 28, baseType: !20, size: 16, flags: DIFlagFixedEnum, elements: !21, identifier: "_ZTS2E3")
81 !20 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned)
82 !21 = !{!22}
83 !22 = !DIEnumerator(name: "A3", value: 65535, isUnsigned: true)
84 ; CHECK: DW_TAG_enumeration_type
85 ; CHECK-DW2-NOT: DW_AT_type
86 ; CHECK-DW4: DW_AT_type{{.*}}"unsigned short"
87 ; CHECK-DW4: DW_AT_enum_class (true)
88 ; CHECK: DW_AT_name ("E3")
89 ; CHECK: DW_TAG_enumerator
90 ; CHECK: DW_AT_name ("A3")
91 ; CHECK-NEXT: DW_AT_const_value (65535)
92
93 ; Test enumeration with a fixed "int" underlying type.
94 !23 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E4", file: !3, line: 34, baseType: !24, size: 32, flags: DIFlagFixedEnum, elements: !25, identifier: "_ZTS2E4")
95 !24 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
96 !25 = !{!26, !27}
97 !26 = !DIEnumerator(name: "A4", value: -2147483648)
98 !27 = !DIEnumerator(name: "B4", value: 2147483647)
99 ; CHECK: DW_TAG_enumeration_type
100 ; CHECK-DW2-NOT: DW_AT_type
101 ; CHECK-DW4: DW_AT_type{{.*}}"int"
102 ; CHECK-DW4: DW_AT_enum_class (true)
103 ; CHECK: DW_AT_name ("E4")
104 ; CHECK: DW_TAG_enumerator
105 ; CHECK: DW_AT_name ("A4")
106 ; CHECK-NEXT: DW_AT_const_value (-2147483648)
107 ; CHECK: DW_TAG_enumerator
108 ; CHECK: DW_AT_name ("B4")
109 ; CHECK-NEXT: DW_AT_const_value (2147483647)
110
111 ; Test enumeration with a fixed "unsigend int" underlying type.
112 !28 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E5", file: !3, line: 41, baseType: !29, size: 32, flags: DIFlagFixedEnum, elements: !30, identifier: "_ZTS2E5")
113 !29 = !DIBasicType(name: "unsigned int", size: 32, encoding: DW_ATE_unsigned)
114 !30 = !{!31}
115 !31 = !DIEnumerator(name: "A5", value: 4294967295, isUnsigned: true)
116 ; CHECK: DW_TAG_enumeration_type
117 ; CHECK-DW2-NOT: DW_AT_type
118 ; CHECK-DW4: DW_AT_type{{.*}}"unsigned int"
119 ; CHECK-DW4: DW_AT_enum_class (true)
120 ; CHECK: DW_AT_name ("E5")
121 ; CHECK: DW_TAG_enumerator
122 ; CHECK: DW_AT_name ("A5")
123 ; CHECK-NEXT: DW_AT_const_value (4294967295)
124
125 ; Test enumeration with a fixed "long long" underlying type.
126 !32 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E6", file: !3, line: 47, baseType: !33, size: 64, flags: DIFlagFixedEnum, elements: !34, identifier: "_ZTS2E6")
127 !33 = !DIBasicType(name: "long long int", size: 64, encoding: DW_ATE_signed)
128 !34 = !{!35, !36}
129 !35 = !DIEnumerator(name: "A6", value: -9223372036854775808)
130 !36 = !DIEnumerator(name: "B6", value: 9223372036854775807)
131 ; CHECK: DW_TAG_enumeration_type
132 ; CHECK-DW2-NOT: DW_AT_type
133 ; CHECK-DW4: DW_AT_type{{.*}}"long long int"
134 ; CHECK-DW4: DW_AT_enum_class (true)
135 ; CHECK: DW_AT_name ("E6")
136 ; CHECK: DW_TAG_enumerator
137 ; CHECK: DW_AT_name ("A6")
138 ; CHECK-NEXT: DW_AT_const_value (-9223372036854775808)
139 ; CHECK: DW_TAG_enumerator
140 ; CHECK: DW_AT_name ("B6")
141 ; CHECK-NEXT: DW_AT_const_value (9223372036854775807)
142
143 ; Test enumeration with a fixed "unsigned long long" underlying type.
144 !37 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E7", file: !3, line: 57, baseType: !38, size: 64, flags: DIFlagFixedEnum, elements: !39, identifier: "_ZTS2E7")
145 !38 = !DIBasicType(name: "long long unsigned int", size: 64, encoding: DW_ATE_unsigned)
146 !39 = !{!40}
147 !40 = !DIEnumerator(name: "A7", value: 18446744073709551615, isUnsigned: true)
148 ; CHECK: DW_TAG_enumeration_type
149 ; CHECK-DW2-NOT: DW_AT_type
150 ; CHECK-DW4: DW_AT_type{{.*}}"long long unsigned int"
151 ; CHECK-DW4: DW_AT_enum_class (true)
152 ; CHECK: DW_AT_name ("E7")
153 ; CHECK: DW_TAG_enumerator
154 ; CHECK: DW_AT_name ("A7")
155 ; CHECK-NEXT: DW_AT_const_value (18446744073709551615)
156
157 ; Test enumeration without a fixed underlying type. The underlying type should
158 ; still be present (for DWARF >= 3), but the DW_AT_enum_class attribute should
159 ; be absent.
160 !41 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "E8", file: !3, line: 63, baseType: !24, size: 32, elements: !42, identifier: "_ZTS2E8")
161 !42 = !{!43, !44}
162 !43 = !DIEnumerator(name: "A8", value: -128)
163 !44 = !DIEnumerator(name: "B8", value: 127)
164 !45 = !{!0, !46, !48, !50, !52, !54, !56, !58, !60}
165 ; CHECK: DW_TAG_enumeration_type
166 ; CHECK-DW2-NOT: DW_AT_type
167 ; CHECK-DW4: DW_AT_type{{.*}}"int"
168 ; CHECK-NOT: DW_AT_enum_class
169 ; CHECK: DW_AT_name ("E8")
170
171 !46 = !DIGlobalVariableExpression(var: !47, expr: !DIExpression())
172 !47 = distinct !DIGlobalVariable(name: "x1", scope: !2, file: !3, line: 12, type: !10, isLocal: false, isDefinition: true)
173 !48 = !DIGlobalVariableExpression(var: !49, expr: !DIExpression())
174 !49 = distinct !DIGlobalVariable(name: "x2", scope: !2, file: !3, line: 21, type: !14, isLocal: false, isDefinition: true)
175 !50 = !DIGlobalVariableExpression(var: !51, expr: !DIExpression())
176 !51 = distinct !DIGlobalVariable(name: "x3", scope: !2, file: !3, line: 28, type: !19, isLocal: false, isDefinition: true)
177 !52 = !DIGlobalVariableExpression(var: !53, expr: !DIExpression())
178 !53 = distinct !DIGlobalVariable(name: "x4", scope: !2, file: !3, line: 34, type: !23, isLocal: false, isDefinition: true)
179 !54 = !DIGlobalVariableExpression(var: !55, expr: !DIExpression())
180 !55 = distinct !DIGlobalVariable(name: "x5", scope: !2, file: !3, line: 41, type: !28, isLocal: false, isDefinition: true)
181 !56 = !DIGlobalVariableExpression(var: !57, expr: !DIExpression())
182 !57 = distinct !DIGlobalVariable(name: "x6", scope: !2, file: !3, line: 50, type: !32, isLocal: false, isDefinition: true)
183 !58 = !DIGlobalVariableExpression(var: !59, expr: !DIExpression())
184 !59 = distinct !DIGlobalVariable(name: "x7", scope: !2, file: !3, line: 57, type: !37, isLocal: false, isDefinition: true)
185 !60 = !DIGlobalVariableExpression(var: !61, expr: !DIExpression())
186 !61 = distinct !DIGlobalVariable(name: "x8", scope: !2, file: !3, line: 63, type: !41, isLocal: false, isDefinition: true)
187 !62 = !{i32 2, !"Debug Info Version", i32 3}
1212 !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
1313 !1 = !DIGlobalVariable(name: "a", scope: null, file: !2, line: 4, type: !3, isLocal: false, isDefinition: true)
1414 !2 = !DIFile(filename: "foo.cpp", directory: "/Users/echristo/tmp")
15 !3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "A", file: !2, line: 1, baseType: !4, size: 32, flags: DIFlagFixedEnum, align: 32, elements: !5)
15 !3 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "A", file: !2, line: 1, baseType: !4, size: 32, align: 32, elements: !5)
1616 !4 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
1717 !5 = !{!6}
1818 !6 = !DIEnumerator(name: "A1", value: 1)
1919 !7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression()) ; [ DW_TAG_enumerator ]
2020 !8 = !DIGlobalVariable(name: "b", scope: null, file: !2, line: 5, type: !9, isLocal: false, isDefinition: true)
21 !9 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "B", file: !2, line: 2, baseType: !10, size: 64, flags: DIFlagFixedEnum, align: 64, elements: !11)
21 !9 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "B", file: !2, line: 2, baseType: !10, size: 64, align: 64, elements: !11)
2222 !10 = !DIBasicType(name: "long unsigned int", size: 64, align: 64, encoding: DW_ATE_unsigned)
2323 !11 = !{!12}
2424 !12 = !DIEnumerator(name: "B1", value: 1) ; [ DW_TAG_enumerator ]
4343 ; CHECK: DW_AT_enum_class [DW_FORM_flag_present] (true)
4444 ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "B")
4545
46 ; CHECK: DW_TAG_enumeration_type
46 ; CHECK: DW_TAG_enumeration_type [6]
4747 ; CHECK-NOT: DW_AT_enum_class
4848 ; CHECK: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "C")
977977 typedef MetadataTest DIEnumeratorTest;
978978
979979 TEST_F(DIEnumeratorTest, get) {
980 auto *N = DIEnumerator::get(Context, 7, false, "name");
980 auto *N = DIEnumerator::get(Context, 7, "name");
981981 EXPECT_EQ(dwarf::DW_TAG_enumerator, N->getTag());
982982 EXPECT_EQ(7, N->getValue());
983 EXPECT_EQ(false, N->isUnsigned());
984983 EXPECT_EQ("name", N->getName());
985 EXPECT_EQ(N, DIEnumerator::get(Context, 7, false, "name"));
986
987 EXPECT_NE(N, DIEnumerator::get(Context, 7, true, "name"));
988 EXPECT_NE(N, DIEnumerator::get(Context, 8, false, "name"));
989 EXPECT_NE(N, DIEnumerator::get(Context, 7, false, "nam"));
984 EXPECT_EQ(N, DIEnumerator::get(Context, 7, "name"));
985
986 EXPECT_NE(N, DIEnumerator::get(Context, 8, "name"));
987 EXPECT_NE(N, DIEnumerator::get(Context, 7, "nam"));
990988
991989 TempDIEnumerator Temp = N->clone();
992990 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));