llvm.org GIT mirror llvm / c4d1909
[DebugInfoMetadata] Added DIFlags interface in DIBasicType. Flags in DIBasicType will be used to pass attributes used in DW_TAG_base_type, such as DW_AT_endianity. Patch by Chirag Patel! Differential Revision: https://reviews.llvm.org/D49610 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@339714 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 2 years ago
16 changed file(s) with 94 addition(s) and 44 deletion(s). Raw diff Collapse all Expand all
1919 defined HANDLE_DW_LNCT || defined HANDLE_DW_MACRO || \
2020 defined HANDLE_DW_RLE || defined HANDLE_DW_CFA || \
2121 defined HANDLE_DW_APPLE_PROPERTY || defined HANDLE_DW_UT || \
22 defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX)
22 defined HANDLE_DWARF_SECTION || defined HANDLE_DW_IDX || \
23 defined HANDLE_DW_END)
2324 #error "Missing macro definition of HANDLE_DW*"
2425 #endif
2526
9798
9899 #ifndef HANDLE_DW_IDX
99100 #define HANDLE_DW_IDX(ID, NAME)
101 #endif
102
103 #ifndef HANDLE_DW_END
104 #define HANDLE_DW_END(ID, NAME)
100105 #endif
101106
102107 HANDLE_DW_TAG(0x0000, null, 2, DWARF)
689694 HANDLE_DW_ATE(0x11, UCS, 5, DWARF)
690695 HANDLE_DW_ATE(0x12, ASCII, 5, DWARF)
691696
697 // DWARF attribute endianity
698 HANDLE_DW_END(0x00, default)
699 HANDLE_DW_END(0x01, big)
700 HANDLE_DW_END(0x02, little)
701
692702 // DWARF virtuality codes.
693703 HANDLE_DW_VIRTUALITY(0x00, none)
694704 HANDLE_DW_VIRTUALITY(0x01, virtual)
908918 #undef HANDLE_DW_UT
909919 #undef HANDLE_DWARF_SECTION
910920 #undef HANDLE_DW_IDX
921 #undef HANDLE_DW_END
149149
150150 enum EndianityEncoding {
151151 // Endianity attribute values
152 DW_END_default = 0x00,
153 DW_END_big = 0x01,
154 DW_END_little = 0x02,
152 #define HANDLE_DW_END(ID, NAME) DW_END_##NAME = ID,
153 #include "llvm/BinaryFormat/Dwarf.def"
155154 DW_END_lo_user = 0x40,
156155 DW_END_hi_user = 0xff
157156 };
187187 /// type.
188188 /// \param Name Type name.
189189 /// \param SizeInBits Size of the type.
190 /// \param Encoding DWARF encoding code, e.g. dwarf::DW_ATE_float.
190 /// \param Encoding DWARF encoding code, e.g., dwarf::DW_ATE_float.
191 /// \param Flags Optional DWARF attributes, e.g., DW_AT_endianity.
191192 DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
192 unsigned Encoding);
193 unsigned Encoding,
194 DINode::DIFlags Flags = DINode::FlagZero);
193195
194196 /// Create debugging information entry for a qualified
195197 /// type, e.g. 'const int'.
4747 HANDLE_DI_FLAG((1 << 24), FixedEnum)
4848 HANDLE_DI_FLAG((1 << 25), Thunk)
4949 HANDLE_DI_FLAG((1 << 26), Trivial)
50 HANDLE_DI_FLAG((1 << 27), BigEndian)
51 HANDLE_DI_FLAG((1 << 28), LittleEndian)
5052
5153 // To avoid needing a dedicated value for IndirectVirtualBase, we use
5254 // the bitwise or of Virtual and FwdDecl, which does not otherwise
5658 #ifdef DI_FLAG_LARGEST_NEEDED
5759 // intended to be used with ADT/BitmaskEnum.h
5860 // NOTE: always must be equal to largest flag, check this when adding new flag
59 HANDLE_DI_FLAG((1 << 26), Largest)
61 HANDLE_DI_FLAG((1 << 28), Largest)
6062 #undef DI_FLAG_LARGEST_NEEDED
6163 #endif
6264
712712 bool isTypePassByReference() const {
713713 return getFlags() & FlagTypePassByReference;
714714 }
715 bool isBigEndian() const { return getFlags() & FlagBigEndian; }
716 bool isLittleEndian() const { return getFlags() & FlagLittleEndian; }
715717
716718 static bool classof(const Metadata *MD) {
717719 switch (MD->getMetadataID()) {
738740
739741 DIBasicType(LLVMContext &C, StorageType Storage, unsigned Tag,
740742 uint64_t SizeInBits, uint32_t AlignInBits, unsigned Encoding,
741 ArrayRef Ops)
743 DIFlags Flags, ArrayRef Ops)
742744 : DIType(C, DIBasicTypeKind, Storage, Tag, 0, SizeInBits, AlignInBits, 0,
743 FlagZero, Ops),
745 Flags, Ops),
744746 Encoding(Encoding) {}
745747 ~DIBasicType() = default;
746748
747749 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
748750 StringRef Name, uint64_t SizeInBits,
749751 uint32_t AlignInBits, unsigned Encoding,
750 StorageType Storage, bool ShouldCreate = true) {
752 DIFlags Flags, StorageType Storage,
753 bool ShouldCreate = true) {
751754 return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
752 SizeInBits, AlignInBits, Encoding, Storage, ShouldCreate);
755 SizeInBits, AlignInBits, Encoding, Flags, Storage,
756 ShouldCreate);
753757 }
754758 static DIBasicType *getImpl(LLVMContext &Context, unsigned Tag,
755759 MDString *Name, uint64_t SizeInBits,
756760 uint32_t AlignInBits, unsigned Encoding,
757 StorageType Storage, bool ShouldCreate = true);
761 DIFlags Flags, StorageType Storage,
762 bool ShouldCreate = true);
758763
759764 TempDIBasicType cloneImpl() const {
760765 return getTemporary(getContext(), getTag(), getName(), getSizeInBits(),
761 getAlignInBits(), getEncoding());
766 getAlignInBits(), getEncoding(), getFlags());
762767 }
763768
764769 public:
765770 DEFINE_MDNODE_GET(DIBasicType, (unsigned Tag, StringRef Name),
766 (Tag, Name, 0, 0, 0))
771 (Tag, Name, 0, 0, 0, FlagZero))
767772 DEFINE_MDNODE_GET(DIBasicType,
768773 (unsigned Tag, StringRef Name, uint64_t SizeInBits,
769 uint32_t AlignInBits, unsigned Encoding),
770 (Tag, Name, SizeInBits, AlignInBits, Encoding))
774 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
775 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
771776 DEFINE_MDNODE_GET(DIBasicType,
772777 (unsigned Tag, MDString *Name, uint64_t SizeInBits,
773 uint32_t AlignInBits, unsigned Encoding),
774 (Tag, Name, SizeInBits, AlignInBits, Encoding))
778 uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
779 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags))
775780
776781 TempDIBasicType clone() const { return cloneImpl(); }
777782
42804280 }
42814281
42824282 /// ParseDIBasicType:
4283 /// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32)
4283 /// ::= !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32,
4284 /// encoding: DW_ATE_encoding, flags: 0)
42844285 bool LLParser::ParseDIBasicType(MDNode *&Result, bool IsDistinct) {
42854286 #define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
42864287 OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_base_type)); \
42874288 OPTIONAL(name, MDStringField, ); \
42884289 OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
42894290 OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
4290 OPTIONAL(encoding, DwarfAttEncodingField, );
4291 OPTIONAL(encoding, DwarfAttEncodingField, ); \
4292 OPTIONAL(flags, DIFlagField, );
42914293 PARSE_MD_FIELDS();
42924294 #undef VISIT_MD_FIELDS
42934295
42944296 Result = GET_OR_DISTINCT(DIBasicType, (Context, tag.Val, name.Val, size.Val,
4295 align.Val, encoding.Val));
4297 align.Val, encoding.Val, flags.Val));
42964298 return false;
42974299 }
42984300
12101210 break;
12111211 }
12121212 case bitc::METADATA_BASIC_TYPE: {
1213 if (Record.size() != 6)
1213 if (Record.size() < 6 || Record.size() > 7)
12141214 return error("Invalid record");
12151215
12161216 IsDistinct = Record[0];
1217 DINode::DIFlags Flags = (Record.size() > 6) ?
1218 static_cast(Record[6]) : DINode::FlagZero;
1219
12171220 MetadataList.assignValue(
12181221 GET_OR_DISTINCT(DIBasicType,
12191222 (Context, Record[1], getMDString(Record[2]), Record[3],
1220 Record[4], Record[5])),
1223 Record[4], Record[5], Flags)),
12211224 NextMetadataNo);
12221225 NextMetadataNo++;
12231226 break;
14851485 Record.push_back(N->getSizeInBits());
14861486 Record.push_back(N->getAlignInBits());
14871487 Record.push_back(N->getEncoding());
1488 Record.push_back(N->getFlags());
14881489
14891490 Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev);
14901491 Record.clear();
858858
859859 uint64_t Size = BTy->getSizeInBits() >> 3;
860860 addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
861
862 if (BTy->isBigEndian())
863 addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_big);
864 else if (BTy->isLittleEndian())
865 addUInt(Buffer, dwarf::DW_AT_endianity, None, dwarf::DW_END_little);
861866 }
862867
863868 void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIDerivedType *DTy) {
17861786 Printer.printInt("align", N->getAlignInBits());
17871787 Printer.printDwarfEnum("encoding", N->getEncoding(),
17881788 dwarf::AttributeEncodingString);
1789 Printer.printDIFlags("flags", N->getFlags());
17891790 Out << ")";
17901791 }
17911792
255255 }
256256
257257 DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,
258 unsigned Encoding) {
258 unsigned Encoding,
259 DINode::DIFlags Flags) {
259260 assert(!Name.empty() && "Unable to create type without name");
260261 return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,
261 0, Encoding);
262 0, Encoding, Flags);
262263 }
263264
264265 DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {
273273 DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
274274 MDString *Name, uint64_t SizeInBits,
275275 uint32_t AlignInBits, unsigned Encoding,
276 StorageType Storage, bool ShouldCreate) {
276 DIFlags Flags, StorageType Storage,
277 bool ShouldCreate) {
277278 assert(isCanonical(Name) && "Expected canonical MDString");
278279 DEFINE_GETIMPL_LOOKUP(DIBasicType,
279 (Tag, Name, SizeInBits, AlignInBits, Encoding));
280 (Tag, Name, SizeInBits, AlignInBits, Encoding, Flags));
280281 Metadata *Ops[] = {nullptr, nullptr, Name};
281 DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding),
282 Ops);
282 DEFINE_GETIMPL_STORE(DIBasicType, (Tag, SizeInBits, AlignInBits, Encoding,
283 Flags), Ops);
283284 }
284285
285286 Optional DIBasicType::getSignedness() const {
375375 uint64_t SizeInBits;
376376 uint32_t AlignInBits;
377377 unsigned Encoding;
378 unsigned Flags;
378379
379380 MDNodeKeyImpl(unsigned Tag, MDString *Name, uint64_t SizeInBits,
380 uint32_t AlignInBits, unsigned Encoding)
381 uint32_t AlignInBits, unsigned Encoding, unsigned Flags)
381382 : Tag(Tag), Name(Name), SizeInBits(SizeInBits), AlignInBits(AlignInBits),
382 Encoding(Encoding) {}
383 Encoding(Encoding), Flags(Flags) {}
383384 MDNodeKeyImpl(const DIBasicType *N)
384385 : Tag(N->getTag()), Name(N->getRawName()), SizeInBits(N->getSizeInBits()),
385 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()) {}
386 AlignInBits(N->getAlignInBits()), Encoding(N->getEncoding()), Flags(N->getFlags()) {}
386387
387388 bool isKeyOf(const DIBasicType *RHS) const {
388389 return Tag == RHS->getTag() && Name == RHS->getRawName() &&
389390 SizeInBits == RHS->getSizeInBits() &&
390391 AlignInBits == RHS->getAlignInBits() &&
391 Encoding == RHS->getEncoding();
392 Encoding == RHS->getEncoding() &&
393 Flags == RHS->getFlags();
392394 }
393395
394396 unsigned getHashValue() const {
885885 AssertDI(N.getTag() == dwarf::DW_TAG_base_type ||
886886 N.getTag() == dwarf::DW_TAG_unspecified_type,
887887 "invalid tag", &N);
888 AssertDI(!(N.isBigEndian() && N.isLittleEndian()) ,
889 "has conflicting flags", &N);
888890 }
889891
890892 void Verifier::visitDIDerivedType(const DIDerivedType &N) {
0 ; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
11 ; RUN: verify-uselistorder %s
22
3 ; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37}
4 !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40}
3 ; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39}
4 !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42}
55
66 ; CHECK: !0 = !DISubrange(count: 3)
77 ; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
9393 ; CHECK-NEXT: !37 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A")
9494 !39 = !DIFile(filename: "file", directory: "dir", source: "int source() { }\0A")
9595 !40 = !DIFile(filename: "file", directory: "dir", checksumkind: CSK_MD5, checksum: "3a420e2646916a475e68de8d48f779f5", source: "int source() { }\0A")
96
97 ; CHECK-NEXT: !38 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian)
98 ; CHECK-NEXT: !39 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian)
99 !41 = !DIBasicType(name: "u64.be", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagBigEndian)
100 !42 = !DIBasicType(name: "u64.le", size: 64, align: 1, encoding: DW_ATE_unsigned, flags: DIFlagLittleEndian)
996996
997997 TEST_F(DIBasicTypeTest, get) {
998998 auto *N =
999 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7);
999 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33, 26, 7,
1000 DINode::FlagZero);
10001001 EXPECT_EQ(dwarf::DW_TAG_base_type, N->getTag());
10011002 EXPECT_EQ("special", N->getName());
10021003 EXPECT_EQ(33u, N->getSizeInBits());
10031004 EXPECT_EQ(26u, N->getAlignInBits());
10041005 EXPECT_EQ(7u, N->getEncoding());
10051006 EXPECT_EQ(0u, N->getLine());
1007 EXPECT_EQ(DINode::FlagZero, N->getFlags());
10061008 EXPECT_EQ(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1007 26, 7));
1009 26, 7, DINode::FlagZero));
10081010
10091011 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
1010 "special", 33, 26, 7));
1012 "special", 33, 26, 7, DINode::FlagZero));
10111013 EXPECT_NE(N,
1012 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7));
1014 DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7,
1015 DINode::FlagZero));
10131016 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
1014 26, 7));
1017 26, 7, DINode::FlagZero));
10151018 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1016 25, 7));
1019 25, 7, DINode::FlagZero));
10171020 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1018 26, 6));
1021 26, 6, DINode::FlagZero));
1022 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1023 26, 7, DINode::FlagBigEndian));
1024 EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1025 26, 7, DINode::FlagLittleEndian));
10191026
10201027 TempDIBasicType Temp = N->clone();
10211028 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
10231030
10241031 TEST_F(DIBasicTypeTest, getWithLargeValues) {
10251032 auto *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special",
1026 UINT64_MAX, UINT32_MAX - 1, 7);
1033 UINT64_MAX, UINT32_MAX - 1, 7, DINode::FlagZero);
10271034 EXPECT_EQ(UINT64_MAX, N->getSizeInBits());
10281035 EXPECT_EQ(UINT32_MAX - 1, N->getAlignInBits());
10291036 }
10371044 EXPECT_EQ(0u, N->getAlignInBits());
10381045 EXPECT_EQ(0u, N->getEncoding());
10391046 EXPECT_EQ(0u, N->getLine());
1047 EXPECT_EQ(DINode::FlagZero, N->getFlags());
10401048 }
10411049
10421050 typedef MetadataTest DITypeTest;
10441052 TEST_F(DITypeTest, clone) {
10451053 // Check that DIType has a specialized clone that returns TempDIType.
10461054 DIType *N = DIBasicType::get(Context, dwarf::DW_TAG_base_type, "int", 32, 32,
1047 dwarf::DW_ATE_signed);
1055 dwarf::DW_ATE_signed, DINode::FlagZero);
10481056
10491057 TempDIType Temp = N->clone();
10501058 EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));