Skip to content

Commit 02a13e7

Browse files
committed
Print raw values for C/C++ enums.
When printing C/C++ enum values, in lieu of having proper metadata for the enum type, try to display a raw value (see SR-6550) rdar://56473712
1 parent 92beb71 commit 02a13e7

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

stdlib/public/core/OutputStream.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,26 @@ internal func _getEnumCaseName<T>(_ value: T) -> UnsafePointer<CChar>?
276276
@_silgen_name("swift_OpaqueSummary")
277277
internal func _opaqueSummary(_ metadata: Any.Type) -> UnsafePointer<CChar>?
278278

279+
/// Obtain a fallback raw value for an enum type without metadata; this
280+
/// should be OK for enums from C/C++ until they have metadata (see
281+
/// <rdar://22036374>). Note that if this turns out to be a Swift Enum
282+
/// with missing metadata, the raw value may be misleading.
283+
@_semantics("optimize.sil.specialize.generic.never")
284+
internal func _fallbackEnumRawValue<T>(_ value: T) -> Int64? {
285+
switch MemoryLayout.size(ofValue: value) {
286+
case 8:
287+
return unsafeBitCast(value, to:Int64.self)
288+
case 4:
289+
return Int64(unsafeBitCast(value, to:Int32.self))
290+
case 2:
291+
return Int64(unsafeBitCast(value, to:Int16.self))
292+
case 1:
293+
return Int64(unsafeBitCast(value, to:Int8.self))
294+
default:
295+
return nil
296+
}
297+
}
298+
279299
/// Do our best to print a value that cannot be printed directly.
280300
@_semantics("optimize.sil.specialize.generic.never")
281301
internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
@@ -342,8 +362,14 @@ internal func _adHocPrint_unlocked<T, TargetStream: TextOutputStream>(
342362
}
343363
target.write(caseName)
344364
} else {
345-
// If the case name is garbage, just print the type name.
346365
printTypeName(mirror.subjectType)
366+
// The case name is garbage; this might be a C/C++ enum without
367+
// metadata, so see if we can get a raw value
368+
if let rawValue = _fallbackEnumRawValue(value) {
369+
target.write("(rawValue: ")
370+
_debugPrint_unlocked(rawValue, &target);
371+
target.write(")")
372+
}
347373
}
348374
if let (_, value) = mirror.children.first {
349375
if Mirror(reflecting: value).displayStyle == .tuple {

test/stdlib/Reflection_objc.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ print("ObjC quick look objects:")
6969
// CHECK-LABEL: ObjC enums:
7070
print("ObjC enums:")
7171

72-
// CHECK-NEXT: We cannot reflect NSComparisonResult yet
73-
print("We cannot reflect \(ComparisonResult.orderedAscending) yet")
72+
// CHECK-NEXT: We cannot properly reflect NSComparisonResult(rawValue: -1) yet
73+
print("We cannot properly reflect \(ComparisonResult.orderedAscending) yet")
7474

7575
// Don't crash when introspecting framework types such as NSURL.
7676
// <rdar://problem/16592777>

0 commit comments

Comments
 (0)