@@ -110,15 +110,14 @@ fn tag_base_type<'ll, 'tcx>(
110
110
_ => false ,
111
111
} ) ;
112
112
113
- // FIXME(mw): Why are niche and regular tags treated differently? Because we want to preserve
114
- // the sign?
115
113
match enum_type_and_layout. layout . variants ( ) {
116
114
// A single-variant enum has no discriminant.
117
115
Variants :: Single { .. } => {
118
116
bug ! ( "tag_base_type() called for enum without tag: {:?}" , enum_type_and_layout)
119
117
}
120
118
121
119
Variants :: Multiple { tag_encoding : TagEncoding :: Niche { .. } , tag, .. } => {
120
+ // Niche tags are always normalized to unsized integers of the correct size.
122
121
match tag. value {
123
122
Primitive :: Int ( t, _) => t,
124
123
Primitive :: F32 => Integer :: I32 ,
@@ -134,26 +133,34 @@ fn tag_base_type<'ll, 'tcx>(
134
133
}
135
134
136
135
Variants :: Multiple { tag_encoding : TagEncoding :: Direct , tag, .. } => {
136
+ // Direct tags preserve the sign.
137
137
tag. value . to_ty ( cx. tcx )
138
138
}
139
139
}
140
140
}
141
141
142
- /// This is a helper function. FIXME: elaborate docs.
142
+ /// Build a DW_TAG_enumeration_type debuginfo node, with the given base type and variants.
143
+ /// This is a helper function and does not register anything in the type map by itself.
144
+ ///
145
+ /// `variants` is an iterator of (discr-value, variant-name).
146
+ ///
147
+ // NOTE: Handling of discriminant values is somewhat inconsistent. They can appear as u128,
148
+ // u64, and i64. Here everything gets mapped to i64 because that's what LLVM's API expects.
143
149
fn build_enumeration_type_di_node < ' ll , ' tcx > (
144
150
cx : & CodegenCx < ' ll , ' tcx > ,
145
151
type_name : & str ,
146
152
base_type : Ty < ' tcx > ,
147
153
variants : & mut dyn Iterator < Item = ( Discr < ' tcx > , Cow < ' tcx , str > ) > ,
148
154
containing_scope : & ' ll DIType ,
149
155
) -> & ' ll DIType {
156
+ let is_unsigned = match base_type. kind ( ) {
157
+ ty:: Int ( _) => false ,
158
+ ty:: Uint ( _) => true ,
159
+ _ => bug ! ( "build_enumeration_type_di_node() called with non-integer tag type." ) ,
160
+ } ;
161
+
150
162
let enumerator_di_nodes: SmallVec < Option < & ' ll DIType > > = variants
151
163
. map ( |( discr, variant_name) | {
152
- let is_unsigned = match discr. ty . kind ( ) {
153
- ty:: Int ( _) => false ,
154
- ty:: Uint ( _) => true ,
155
- _ => bug ! ( "build_enumeration_type_di_node() called with non-integer tag type." ) ,
156
- } ;
157
164
unsafe {
158
165
Some ( llvm:: LLVMRustDIBuilderCreateEnumerator (
159
166
DIB ( cx) ,
0 commit comments