Skip to content

Commit 08dc66e

Browse files
Re-commit r324489: [DebugInfo] Improvements to representation of enumeration types (PR36168)
Differential Revision: https://reviews.llvm.org/D42734 llvm-svn: 324899
1 parent b941f5d commit 08dc66e

File tree

16 files changed

+392
-51
lines changed

16 files changed

+392
-51
lines changed

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ enum MetadataCodes {
279279
METADATA_ATTACHMENT = 11, // [m x [value, [n x [id, mdnode]]]
280280
METADATA_GENERIC_DEBUG = 12, // [distinct, tag, vers, header, n x md num]
281281
METADATA_SUBRANGE = 13, // [distinct, count, lo]
282-
METADATA_ENUMERATOR = 14, // [distinct, value, name]
282+
METADATA_ENUMERATOR = 14, // [isUnsigned|distinct, value, name]
283283
METADATA_BASIC_TYPE = 15, // [distinct, tag, name, size, align, enc]
284284
METADATA_FILE = 16, // [distinct, filename, directory, checksumkind, checksum]
285285
METADATA_DERIVED_TYPE = 17, // [distinct, ...]

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ namespace llvm {
166166
DIFile *File);
167167

168168
/// Create a single enumerator value.
169-
DIEnumerator *createEnumerator(StringRef Name, int64_t Val);
169+
DIEnumerator *createEnumerator(StringRef Name, int64_t Val, bool IsUnsigned = false);
170170

171171
/// Create a DWARF unspecified type.
172172
DIBasicType *createUnspecifiedType(StringRef Name);
@@ -487,10 +487,11 @@ namespace llvm {
487487
/// \param Elements Enumeration elements.
488488
/// \param UnderlyingType Underlying type of a C++11/ObjC fixed enum.
489489
/// \param UniqueIdentifier A unique identifier for the enum.
490+
/// \param IsFixed Boolean flag indicate if this is C++11/ObjC fixed enum.
490491
DICompositeType *createEnumerationType(
491492
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
492493
uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,
493-
DIType *UnderlyingType, StringRef UniqueIdentifier = "");
494+
DIType *UnderlyingType, StringRef UniqueIdentifier = "", bool IsFixed = false);
494495

495496
/// Create subroutine type.
496497
/// \param ParameterTypes An array of subroutine parameter types. This

llvm/include/llvm/IR/DebugInfoFlags.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ HANDLE_DI_FLAG((1 << 20), NoReturn)
4545
HANDLE_DI_FLAG((1 << 21), MainSubprogram)
4646
HANDLE_DI_FLAG((1 << 22), TypePassByValue)
4747
HANDLE_DI_FLAG((1 << 23), TypePassByReference)
48+
HANDLE_DI_FLAG((1 << 24), FixedEnum)
4849

4950
// To avoid needing a dedicated value for IndirectVirtualBase, we use
5051
// the bitwise or of Virtual and FwdDecl, which does not otherwise
@@ -54,7 +55,7 @@ HANDLE_DI_FLAG((1 << 2) | (1 << 5), IndirectVirtualBase)
5455
#ifdef DI_FLAG_LARGEST_NEEDED
5556
// intended to be used with ADT/BitmaskEnum.h
5657
// NOTE: always must be equal to largest flag, check this when adding new flag
57-
HANDLE_DI_FLAG((1 << 23), Largest)
58+
HANDLE_DI_FLAG((1 << 24), Largest)
5859
#undef DI_FLAG_LARGEST_NEEDED
5960
#endif
6061

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -396,36 +396,38 @@ class DIEnumerator : public DINode {
396396
friend class MDNode;
397397

398398
int64_t Value;
399-
400399
DIEnumerator(LLVMContext &C, StorageType Storage, int64_t Value,
401-
ArrayRef<Metadata *> Ops)
400+
bool IsUnsigned, ArrayRef<Metadata *> Ops)
402401
: DINode(C, DIEnumeratorKind, Storage, dwarf::DW_TAG_enumerator, Ops),
403-
Value(Value) {}
402+
Value(Value) {
403+
SubclassData32 = IsUnsigned;
404+
}
404405
~DIEnumerator() = default;
405406

406407
static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
407-
StringRef Name, StorageType Storage,
408-
bool ShouldCreate = true) {
409-
return getImpl(Context, Value, getCanonicalMDString(Context, Name), Storage,
410-
ShouldCreate);
408+
bool IsUnsigned, StringRef Name,
409+
StorageType Storage, bool ShouldCreate = true) {
410+
return getImpl(Context, Value, IsUnsigned,
411+
getCanonicalMDString(Context, Name), Storage, ShouldCreate);
411412
}
412413
static DIEnumerator *getImpl(LLVMContext &Context, int64_t Value,
413-
MDString *Name, StorageType Storage,
414-
bool ShouldCreate = true);
414+
bool IsUnsigned, MDString *Name,
415+
StorageType Storage, bool ShouldCreate = true);
415416

416417
TempDIEnumerator cloneImpl() const {
417-
return getTemporary(getContext(), getValue(), getName());
418+
return getTemporary(getContext(), getValue(), isUnsigned(), getName());
418419
}
419420

420421
public:
421-
DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, StringRef Name),
422-
(Value, Name))
423-
DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, MDString *Name),
424-
(Value, Name))
422+
DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, StringRef Name),
423+
(Value, IsUnsigned, Name))
424+
DEFINE_MDNODE_GET(DIEnumerator, (int64_t Value, bool IsUnsigned, MDString *Name),
425+
(Value, IsUnsigned, Name))
425426

426427
TempDIEnumerator clone() const { return cloneImpl(); }
427428

428429
int64_t getValue() const { return Value; }
430+
bool isUnsigned() const { return SubclassData32; }
429431
StringRef getName() const { return getStringOperand(0); }
430432

431433
MDString *getRawName() const { return getOperandAs<MDString>(0); }

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3636,6 +3636,22 @@ struct MDSignedOrMDField : MDEitherFieldImpl<MDSignedField, MDField> {
36363636
}
36373637
};
36383638

3639+
struct MDSignedOrUnsignedField
3640+
: MDEitherFieldImpl<MDSignedField, MDUnsignedField> {
3641+
MDSignedOrUnsignedField() : ImplTy(MDSignedField(0), MDUnsignedField(0)) {}
3642+
3643+
bool isMDSignedField() const { return WhatIs == IsTypeA; }
3644+
bool isMDUnsignedField() const { return WhatIs == IsTypeB; }
3645+
int64_t getMDSignedValue() const {
3646+
assert(isMDSignedField() && "Wrong field type");
3647+
return A.Val;
3648+
}
3649+
uint64_t getMDUnsignedValue() const {
3650+
assert(isMDUnsignedField() && "Wrong field type");
3651+
return B.Val;
3652+
}
3653+
};
3654+
36393655
} // end anonymous namespace
36403656

36413657
namespace llvm {
@@ -3912,6 +3928,27 @@ bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
39123928
return true;
39133929
}
39143930

3931+
template <>
3932+
bool LLParser::ParseMDField(LocTy Loc, StringRef Name,
3933+
MDSignedOrUnsignedField &Result) {
3934+
if (Lex.getKind() != lltok::APSInt)
3935+
return false;
3936+
3937+
if (Lex.getAPSIntVal().isSigned()) {
3938+
MDSignedField Res = Result.A;
3939+
if (ParseMDField(Loc, Name, Res))
3940+
return true;
3941+
Result.assign(Res);
3942+
return false;
3943+
}
3944+
3945+
MDUnsignedField Res = Result.B;
3946+
if (ParseMDField(Loc, Name, Res))
3947+
return true;
3948+
Result.assign(Res);
3949+
return false;
3950+
}
3951+
39153952
template <>
39163953
bool LLParser::ParseMDField(LocTy Loc, StringRef Name, MDStringField &Result) {
39173954
LocTy ValueLoc = Lex.getLoc();
@@ -4077,15 +4114,24 @@ bool LLParser::ParseDISubrange(MDNode *&Result, bool IsDistinct) {
40774114
}
40784115

40794116
/// ParseDIEnumerator:
4080-
/// ::= !DIEnumerator(value: 30, name: "SomeKind")
4117+
/// ::= !DIEnumerator(value: 30, isUnsigned: true, name: "SomeKind")
40814118
bool LLParser::ParseDIEnumerator(MDNode *&Result, bool IsDistinct) {
40824119
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
40834120
REQUIRED(name, MDStringField, ); \
4084-
REQUIRED(value, MDSignedField, );
4121+
REQUIRED(value, MDSignedOrUnsignedField, ); \
4122+
OPTIONAL(isUnsigned, MDBoolField, (false));
40854123
PARSE_MD_FIELDS();
40864124
#undef VISIT_MD_FIELDS
40874125

4088-
Result = GET_OR_DISTINCT(DIEnumerator, (Context, value.Val, name.Val));
4126+
if (isUnsigned.Val && value.isMDSignedField())
4127+
return TokError("unsigned enumerator with negative value");
4128+
4129+
int64_t Value = value.isMDSignedField()
4130+
? value.getMDSignedValue()
4131+
: static_cast<int64_t>(value.getMDUnsignedValue());
4132+
Result =
4133+
GET_OR_DISTINCT(DIEnumerator, (Context, Value, isUnsigned.Val, name.Val));
4134+
40894135
return false;
40904136
}
40914137

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,10 +1200,11 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
12001200
if (Record.size() != 3)
12011201
return error("Invalid record");
12021202

1203-
IsDistinct = Record[0];
1203+
IsDistinct = Record[0] & 1;
1204+
bool IsUnsigned = Record[0] & 2;
12041205
MetadataList.assignValue(
12051206
GET_OR_DISTINCT(DIEnumerator, (Context, unrotateSign(Record[1]),
1206-
getMDString(Record[2]))),
1207+
IsUnsigned, getMDString(Record[2]))),
12071208
NextMetadataNo);
12081209
NextMetadataNo++;
12091210
break;

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@ void ModuleBitcodeWriter::writeDISubrange(const DISubrange *N,
14571457
void ModuleBitcodeWriter::writeDIEnumerator(const DIEnumerator *N,
14581458
SmallVectorImpl<uint64_t> &Record,
14591459
unsigned Abbrev) {
1460-
Record.push_back(N->isDistinct());
1460+
Record.push_back((N->isUnsigned() << 1) | N->isDistinct());
14611461
Record.push_back(rotateSign(N->getValue()));
14621462
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
14631463

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,6 +1427,15 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
14271427
}
14281428

14291429
void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
1430+
const DIType *DTy = resolve(CTy->getBaseType());
1431+
bool IsUnsigned = DTy && isUnsignedDIType(DD, DTy);
1432+
if (DTy && DD->getDwarfVersion() >= 3)
1433+
addType(Buffer, DTy);
1434+
if (DD->getDwarfVersion() >= 4 && (CTy->getFlags() & DINode::FlagFixedEnum)) {
1435+
assert(DTy);
1436+
addFlag(Buffer, dwarf::DW_AT_enum_class);
1437+
}
1438+
14301439
DINodeArray Elements = CTy->getElements();
14311440

14321441
// Add enumerators to enumeration type.
@@ -1436,16 +1445,10 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
14361445
DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
14371446
StringRef Name = Enum->getName();
14381447
addString(Enumerator, dwarf::DW_AT_name, Name);
1439-
int64_t Value = Enum->getValue();
1440-
addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata,
1441-
Value);
1448+
auto Value = static_cast<uint64_t>(Enum->getValue());
1449+
addConstantValue(Enumerator, IsUnsigned, Value);
14421450
}
14431451
}
1444-
const DIType *DTy = resolve(CTy->getBaseType());
1445-
if (DTy) {
1446-
addType(Buffer, DTy);
1447-
addFlag(Buffer, dwarf::DW_AT_enum_class);
1448-
}
14491452
}
14501453

14511454
void DwarfUnit::constructContainingTypeDIEs() {

llvm/lib/IR/AsmWriter.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1629,7 +1629,13 @@ static void writeDIEnumerator(raw_ostream &Out, const DIEnumerator *N,
16291629
Out << "!DIEnumerator(";
16301630
MDFieldPrinter Printer(Out);
16311631
Printer.printString("name", N->getName(), /* ShouldSkipEmpty */ false);
1632-
Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
1632+
if (N->isUnsigned()) {
1633+
auto Value = static_cast<uint64_t>(N->getValue());
1634+
Printer.printInt("value", Value, /* ShouldSkipZero */ false);
1635+
Printer.printBool("isUnsigned", true);
1636+
} else {
1637+
Printer.printInt("value", N->getValue(), /* ShouldSkipZero */ false);
1638+
}
16331639
Out << ")";
16341640
}
16351641

llvm/lib/IR/DIBuilder.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,9 +233,10 @@ DIMacroFile *DIBuilder::createTempMacroFile(DIMacroFile *Parent,
233233
return MF;
234234
}
235235

236-
DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val) {
236+
DIEnumerator *DIBuilder::createEnumerator(StringRef Name, int64_t Val,
237+
bool IsUnsigned) {
237238
assert(!Name.empty() && "Unable to create enumerator without name");
238-
return DIEnumerator::get(VMContext, Val, Name);
239+
return DIEnumerator::get(VMContext, Val, IsUnsigned, Name);
239240
}
240241

241242
DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) {
@@ -492,11 +493,12 @@ DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,
492493
DICompositeType *DIBuilder::createEnumerationType(
493494
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
494495
uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,
495-
DIType *UnderlyingType, StringRef UniqueIdentifier) {
496+
DIType *UnderlyingType, StringRef UniqueIdentifier, bool IsFixed) {
496497
auto *CTy = DICompositeType::get(
497498
VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber,
498499
getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0,
499-
DINode::FlagZero, Elements, 0, nullptr, nullptr, UniqueIdentifier);
500+
IsFixed ? DINode::FlagFixedEnum : DINode::FlagZero, Elements, 0, nullptr,
501+
nullptr, UniqueIdentifier);
500502
AllEnumTypes.push_back(CTy);
501503
trackIfUnresolved(CTy);
502504
return CTy;

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,12 @@ DISubrange *DISubrange::getImpl(LLVMContext &Context, Metadata *CountNode,
263263
}
264264

265265
DIEnumerator *DIEnumerator::getImpl(LLVMContext &Context, int64_t Value,
266-
MDString *Name, StorageType Storage,
267-
bool ShouldCreate) {
266+
bool IsUnsigned, MDString *Name,
267+
StorageType Storage, bool ShouldCreate) {
268268
assert(isCanonical(Name) && "Expected canonical MDString");
269-
DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, Name));
269+
DEFINE_GETIMPL_LOOKUP(DIEnumerator, (Value, IsUnsigned, Name));
270270
Metadata *Ops[] = {Name};
271-
DEFINE_GETIMPL_STORE(DIEnumerator, (Value), Ops);
271+
DEFINE_GETIMPL_STORE(DIEnumerator, (Value, IsUnsigned), Ops);
272272
}
273273

274274
DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,

llvm/lib/IR/LLVMContextImpl.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,13 +354,17 @@ template <> struct MDNodeKeyImpl<DISubrange> {
354354
template <> struct MDNodeKeyImpl<DIEnumerator> {
355355
int64_t Value;
356356
MDString *Name;
357+
bool IsUnsigned;
357358

358-
MDNodeKeyImpl(int64_t Value, MDString *Name) : Value(Value), Name(Name) {}
359+
MDNodeKeyImpl(int64_t Value, bool IsUnsigned, MDString *Name)
360+
: Value(Value), Name(Name), IsUnsigned(IsUnsigned) {}
359361
MDNodeKeyImpl(const DIEnumerator *N)
360-
: Value(N->getValue()), Name(N->getRawName()) {}
362+
: Value(N->getValue()), Name(N->getRawName()),
363+
IsUnsigned(N->isUnsigned()) {}
361364

362365
bool isKeyOf(const DIEnumerator *RHS) const {
363-
return Value == RHS->getValue() && Name == RHS->getRawName();
366+
return Value == RHS->getValue() && IsUnsigned == RHS->isUnsigned() &&
367+
Name == RHS->getRawName();
364368
}
365369

366370
unsigned getHashValue() const { return hash_combine(Value, Name); }

0 commit comments

Comments
 (0)