Skip to content

Commit bf4cb17

Browse files
committed
Add DISubrangeType
An Ada program can have types that are subranges of other types. This patch adds a new DIType node, DISubrangeType, to represent this concept. I considered extending the existing DISubrange to do this, but as DISubrange does not derive from DIType, that approach seemed more disruptive. A DISubrangeType can be used both as an ordinary type, but also as the type of an array index. This is also important for Ada.
1 parent 36fba1c commit bf4cb17

File tree

18 files changed

+511
-7
lines changed

18 files changed

+511
-7
lines changed

llvm/include/llvm-c/DebugInfo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ enum {
172172
LLVMDIEnumeratorMetadataKind,
173173
LLVMDIBasicTypeMetadataKind,
174174
LLVMDIDerivedTypeMetadataKind,
175+
LLVMDISubrangeTypeMetadataKind,
175176
LLVMDICompositeTypeMetadataKind,
176177
LLVMDISubroutineTypeMetadataKind,
177178
LLVMDIFileMetadataKind,

llvm/include/llvm/Bitcode/LLVMBitCodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ enum MetadataCodes {
385385
METADATA_GENERIC_SUBRANGE = 45, // [distinct, count, lo, up, stride]
386386
METADATA_ARG_LIST = 46, // [n x [type num, value num]]
387387
METADATA_ASSIGN_ID = 47, // [distinct, ...]
388+
METADATA_SUBRANGE_TYPE = 48, // [distinct, ...]
388389
};
389390

390391
// The constants block (CONSTANTS_BLOCK_ID) describes emission for each

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,26 @@ namespace llvm {
667667
/// If \p Implicit is true, also set FlagArtificial.
668668
static DIType *createObjectPointerType(DIType *Ty, bool Implicit);
669669

670+
/// Create a type describing a subrange of another type.
671+
/// \param Scope Scope in which this set is defined.
672+
/// \param Name Set name.
673+
/// \param File File where this set is defined.
674+
/// \param LineNo Line number.
675+
/// \param SizeInBits Size.
676+
/// \param AlignInBits Alignment.
677+
/// \param Flags Flags to encode attributes.
678+
/// \param Ty Base type.
679+
/// \param LowerBound Lower bound.
680+
/// \param UpperBound Upper bound.
681+
/// \param Stride Stride, if any.
682+
/// \param Bias Bias, if any.
683+
DISubrangeType *
684+
createSubrangeType(StringRef Name, DIFile *File, unsigned LineNo,
685+
DIScope *Scope, uint64_t SizeInBits,
686+
uint32_t AlignInBits, DINode::DIFlags Flags, DIType *Ty,
687+
Metadata *LowerBound, Metadata *UpperBound,
688+
Metadata *Stride, Metadata *Bias);
689+
670690
/// Create a permanent forward-declared type.
671691
DICompositeType *
672692
createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F,

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 94 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ class DINode : public MDNode {
200200
case DIEnumeratorKind:
201201
case DIBasicTypeKind:
202202
case DIStringTypeKind:
203+
case DISubrangeTypeKind:
203204
case DIDerivedTypeKind:
204205
case DICompositeTypeKind:
205206
case DISubroutineTypeKind:
@@ -342,9 +343,6 @@ class DIAssignID : public MDNode {
342343
};
343344

344345
/// Array subrange.
345-
///
346-
/// TODO: Merge into node for DW_TAG_array_type, which should have a custom
347-
/// type.
348346
class DISubrange : public DINode {
349347
friend class LLVMContextImpl;
350348
friend class MDNode;
@@ -550,6 +548,7 @@ class DIScope : public DINode {
550548
return false;
551549
case DIBasicTypeKind:
552550
case DIStringTypeKind:
551+
case DISubrangeTypeKind:
553552
case DIDerivedTypeKind:
554553
case DICompositeTypeKind:
555554
case DISubroutineTypeKind:
@@ -808,6 +807,7 @@ class DIType : public DIScope {
808807
return false;
809808
case DIBasicTypeKind:
810809
case DIStringTypeKind:
810+
case DISubrangeTypeKind:
811811
case DIDerivedTypeKind:
812812
case DICompositeTypeKind:
813813
case DISubroutineTypeKind:
@@ -1167,6 +1167,97 @@ inline bool operator!=(DIDerivedType::PtrAuthData Lhs,
11671167
return !(Lhs == Rhs);
11681168
}
11691169

1170+
/// Subrange type. This is somewhat similar to DISubrange, but it
1171+
/// is also a DIType.
1172+
class DISubrangeType : public DIType {
1173+
public:
1174+
typedef PointerUnion<ConstantInt *, DIVariable *, DIExpression *> BoundType;
1175+
1176+
private:
1177+
friend class LLVMContextImpl;
1178+
friend class MDNode;
1179+
1180+
DISubrangeType(LLVMContext &C, StorageType Storage, unsigned Line,
1181+
uint64_t SizeInBits, uint32_t AlignInBits, DIFlags Flags,
1182+
ArrayRef<Metadata *> Ops);
1183+
1184+
~DISubrangeType() = default;
1185+
1186+
static DISubrangeType *
1187+
getImpl(LLVMContext &Context, StringRef Name, DIFile *File, unsigned Line,
1188+
DIScope *Scope, uint64_t SizeInBits, uint32_t AlignInBits,
1189+
DIFlags Flags, DIType *BaseType, Metadata *LowerBound,
1190+
Metadata *UpperBound, Metadata *Stride, Metadata *Bias,
1191+
StorageType Storage, bool ShouldCreate = true) {
1192+
return getImpl(Context, getCanonicalMDString(Context, Name), File, Line,
1193+
Scope, SizeInBits, AlignInBits, Flags, BaseType, LowerBound,
1194+
UpperBound, Stride, Bias, Storage, ShouldCreate);
1195+
}
1196+
1197+
static DISubrangeType *getImpl(LLVMContext &Context, MDString *Name,
1198+
Metadata *File, unsigned Line, Metadata *Scope,
1199+
uint64_t SizeInBits, uint32_t AlignInBits,
1200+
DIFlags Flags, Metadata *BaseType,
1201+
Metadata *LowerBound, Metadata *UpperBound,
1202+
Metadata *Stride, Metadata *Bias,
1203+
StorageType Storage, bool ShouldCreate = true);
1204+
1205+
TempDISubrangeType cloneImpl() const {
1206+
return getTemporary(getContext(), getName(), getFile(), getLine(),
1207+
getScope(), getSizeInBits(), getAlignInBits(),
1208+
getFlags(), getBaseType(), getRawLowerBound(),
1209+
getRawUpperBound(), getRawStride(), getRawBias());
1210+
}
1211+
1212+
BoundType convertRawToBound(Metadata *IN) const;
1213+
1214+
public:
1215+
DEFINE_MDNODE_GET(DISubrangeType,
1216+
(MDString * Name, Metadata *File, unsigned Line,
1217+
Metadata *Scope, uint64_t SizeInBits, uint32_t AlignInBits,
1218+
DIFlags Flags, Metadata *BaseType, Metadata *LowerBound,
1219+
Metadata *UpperBound, Metadata *Stride, Metadata *Bias),
1220+
(Name, File, Line, Scope, SizeInBits, AlignInBits, Flags,
1221+
BaseType, LowerBound, UpperBound, Stride, Bias))
1222+
DEFINE_MDNODE_GET(DISubrangeType,
1223+
(StringRef Name, DIFile *File, unsigned Line,
1224+
DIScope *Scope, uint64_t SizeInBits, uint32_t AlignInBits,
1225+
DIFlags Flags, DIType *BaseType, Metadata *LowerBound,
1226+
Metadata *UpperBound, Metadata *Stride, Metadata *Bias),
1227+
(Name, File, Line, Scope, SizeInBits, AlignInBits, Flags,
1228+
BaseType, LowerBound, UpperBound, Stride, Bias))
1229+
1230+
TempDISubrangeType clone() const { return cloneImpl(); }
1231+
1232+
/// Get the base type this is derived from.
1233+
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
1234+
Metadata *getRawBaseType() const { return getOperand(3); }
1235+
1236+
Metadata *getRawLowerBound() const { return getOperand(4).get(); }
1237+
1238+
Metadata *getRawUpperBound() const { return getOperand(5).get(); }
1239+
1240+
Metadata *getRawStride() const { return getOperand(6).get(); }
1241+
1242+
Metadata *getRawBias() const { return getOperand(7).get(); }
1243+
1244+
BoundType getLowerBound() const {
1245+
return convertRawToBound(getRawLowerBound());
1246+
}
1247+
1248+
BoundType getUpperBound() const {
1249+
return convertRawToBound(getRawUpperBound());
1250+
}
1251+
1252+
BoundType getStride() const { return convertRawToBound(getRawStride()); }
1253+
1254+
BoundType getBias() const { return convertRawToBound(getRawBias()); }
1255+
1256+
static bool classof(const Metadata *MD) {
1257+
return MD->getMetadataID() == DISubrangeTypeKind;
1258+
}
1259+
};
1260+
11701261
/// Composite types.
11711262
///
11721263
/// TODO: Detach from DerivedTypeBase (split out MDEnumType?).

llvm/include/llvm/IR/Metadata.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile)
118118
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DICommonBlock)
119119
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIStringType)
120120
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGenericSubrange)
121+
HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DISubrangeType)
121122

122123
#undef HANDLE_METADATA
123124
#undef HANDLE_METADATA_LEAF

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5318,6 +5318,50 @@ bool LLParser::parseGenericDINode(MDNode *&Result, bool IsDistinct) {
53185318
return false;
53195319
}
53205320

5321+
/// parseDISubrangeType:
5322+
/// ::= !DISubrangeType(name: "whatever", file: !0,
5323+
/// line: 7, scope: !1, baseType: !2, size: 32,
5324+
/// align: 32, flags: 0, lowerBound: !3
5325+
/// upperBound: !4, stride: !5, bias: !6)
5326+
bool LLParser::parseDISubrangeType(MDNode *&Result, bool IsDistinct) {
5327+
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
5328+
OPTIONAL(name, MDStringField, ); \
5329+
OPTIONAL(file, MDField, ); \
5330+
OPTIONAL(line, LineField, ); \
5331+
OPTIONAL(scope, MDField, ); \
5332+
OPTIONAL(baseType, MDField, ); \
5333+
OPTIONAL(size, MDUnsignedField, (0, UINT64_MAX)); \
5334+
OPTIONAL(align, MDUnsignedField, (0, UINT32_MAX)); \
5335+
OPTIONAL(flags, DIFlagField, ); \
5336+
OPTIONAL(lowerBound, MDSignedOrMDField, ); \
5337+
OPTIONAL(upperBound, MDSignedOrMDField, ); \
5338+
OPTIONAL(stride, MDSignedOrMDField, ); \
5339+
OPTIONAL(bias, MDSignedOrMDField, );
5340+
PARSE_MD_FIELDS();
5341+
#undef VISIT_MD_FIELDS
5342+
5343+
auto convToMetadata = [&](MDSignedOrMDField Bound) -> Metadata * {
5344+
if (Bound.isMDSignedField())
5345+
return ConstantAsMetadata::get(ConstantInt::getSigned(
5346+
Type::getInt64Ty(Context), Bound.getMDSignedValue()));
5347+
if (Bound.isMDField())
5348+
return Bound.getMDFieldValue();
5349+
return nullptr;
5350+
};
5351+
5352+
Metadata *LowerBound = convToMetadata(lowerBound);
5353+
Metadata *UpperBound = convToMetadata(upperBound);
5354+
Metadata *Stride = convToMetadata(stride);
5355+
Metadata *Bias = convToMetadata(bias);
5356+
5357+
Result = GET_OR_DISTINCT(DISubrangeType,
5358+
(Context, name.Val, file.Val, line.Val, scope.Val,
5359+
size.Val, align.Val, flags.Val, baseType.Val,
5360+
LowerBound, UpperBound, Stride, Bias));
5361+
5362+
return false;
5363+
}
5364+
53215365
/// parseDISubrange:
53225366
/// ::= !DISubrange(count: 30, lowerBound: 2)
53235367
/// ::= !DISubrange(count: !node, lowerBound: 2)

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,24 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
15991599
NextMetadataNo++;
16001600
break;
16011601
}
1602+
case bitc::METADATA_SUBRANGE_TYPE: {
1603+
if (Record.size() != 13)
1604+
return error("Invalid record");
1605+
1606+
IsDistinct = Record[0];
1607+
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7]);
1608+
MetadataList.assignValue(
1609+
GET_OR_DISTINCT(DISubrangeType,
1610+
(Context, getMDString(Record[1]),
1611+
getMDOrNull(Record[2]), Record[3],
1612+
getMDOrNull(Record[4]), Record[5], Record[6], Flags,
1613+
getDITypeRefOrNull(Record[8]), getMDOrNull(Record[9]),
1614+
getMDOrNull(Record[10]), getMDOrNull(Record[11]),
1615+
getMDOrNull(Record[12]))),
1616+
NextMetadataNo);
1617+
NextMetadataNo++;
1618+
break;
1619+
}
16021620
case bitc::METADATA_COMPOSITE_TYPE: {
16031621
if (Record.size() < 16 || Record.size() > 25)
16041622
return error("Invalid record");

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ class ModuleBitcodeWriter : public ModuleBitcodeWriterBase {
327327
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
328328
void writeDIDerivedType(const DIDerivedType *N,
329329
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
330+
void writeDISubrangeType(const DISubrangeType *N,
331+
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
330332
void writeDICompositeType(const DICompositeType *N,
331333
SmallVectorImpl<uint64_t> &Record, unsigned Abbrev);
332334
void writeDISubroutineType(const DISubroutineType *N,
@@ -1930,6 +1932,27 @@ void ModuleBitcodeWriter::writeDIDerivedType(const DIDerivedType *N,
19301932
Record.clear();
19311933
}
19321934

1935+
void ModuleBitcodeWriter::writeDISubrangeType(const DISubrangeType *N,
1936+
SmallVectorImpl<uint64_t> &Record,
1937+
unsigned Abbrev) {
1938+
Record.push_back(N->isDistinct());
1939+
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
1940+
Record.push_back(VE.getMetadataOrNullID(N->getFile()));
1941+
Record.push_back(N->getLine());
1942+
Record.push_back(VE.getMetadataOrNullID(N->getScope()));
1943+
Record.push_back(N->getSizeInBits());
1944+
Record.push_back(N->getAlignInBits());
1945+
Record.push_back(N->getFlags());
1946+
Record.push_back(VE.getMetadataOrNullID(N->getBaseType()));
1947+
Record.push_back(VE.getMetadataOrNullID(N->getRawLowerBound()));
1948+
Record.push_back(VE.getMetadataOrNullID(N->getRawUpperBound()));
1949+
Record.push_back(VE.getMetadataOrNullID(N->getRawStride()));
1950+
Record.push_back(VE.getMetadataOrNullID(N->getRawBias()));
1951+
1952+
Stream.EmitRecord(bitc::METADATA_SUBRANGE_TYPE, Record, Abbrev);
1953+
Record.clear();
1954+
}
1955+
19331956
void ModuleBitcodeWriter::writeDICompositeType(
19341957
const DICompositeType *N, SmallVectorImpl<uint64_t> &Record,
19351958
unsigned Abbrev) {

llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ uint64_t DebugHandlerBase::getBaseTypeSize(const DIType *Ty) {
161161
DIType *BaseType = nullptr;
162162
if (const DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty))
163163
BaseType = DDTy->getBaseType();
164+
else if (const DISubrangeType *SRTy = dyn_cast<DISubrangeType>(Ty))
165+
BaseType = SRTy->getBaseType();
164166

165167
if (!BaseType)
166168
return 0;
@@ -186,6 +188,12 @@ bool DebugHandlerBase::isUnsignedDIType(const DIType *Ty) {
186188
return true;
187189
}
188190

191+
if (auto *SRTy = dyn_cast<DISubrangeType>(Ty)) {
192+
Ty = SRTy->getBaseType();
193+
if (!Ty)
194+
return false;
195+
}
196+
189197
if (auto *CTy = dyn_cast<DICompositeType>(Ty)) {
190198
if (CTy->getTag() == dwarf::DW_TAG_enumeration_type) {
191199
if (!(Ty = CTy->getBaseType()))

0 commit comments

Comments
 (0)