Merge pull request #1223 from spevans/pr_objcbool

diff --git a/Foundation/FileManager.swift b/Foundation/FileManager.swift
index f7ca2e1..0f8e634 100644
--- a/Foundation/FileManager.swift
+++ b/Foundation/FileManager.swift
@@ -158,7 +158,7 @@
                 } else if let attr = attributes {
                     try self.setAttributes(attr, ofItemAtPath: path)
                 }
-            } else if isDir {
+            } else if isDir.boolValue {
                 return
             } else {
                 throw _NSErrorWithErrno(EEXIST, reading: false, path: path)
@@ -406,9 +406,9 @@
     }
     
     open func linkItem(atPath srcPath: String, toPath dstPath: String) throws {
-        var isDir = false
+        var isDir: ObjCBool = false
         if self.fileExists(atPath: srcPath, isDirectory: &isDir) {
-            if !isDir {
+            if !isDir.boolValue {
                 // TODO: Symlinks should be copied instead of hard-linked.
                 if link(srcPath, dstPath) == -1 {
                     throw _NSErrorWithErrno(errno, reading: false, path: srcPath)
@@ -532,12 +532,13 @@
             if let isDirectory = isDirectory {
                 if (s.st_mode & S_IFMT) == S_IFLNK {
                     if stat(path, &s) >= 0 {
-                        isDirectory.pointee = (s.st_mode & S_IFMT) == S_IFDIR
+                        isDirectory.pointee = ObjCBool((s.st_mode & S_IFMT) == S_IFDIR)
                     } else {
                         return false
                     }
                 } else {
-                    isDirectory.pointee = (s.st_mode & S_IFMT) == S_IFDIR
+                    let isDir = (s.st_mode & S_IFMT) == S_IFDIR
+                    isDirectory.pointee = ObjCBool(isDir)
                 }
             }
 
diff --git a/Foundation/NSAttributedString.swift b/Foundation/NSAttributedString.swift
index 17dbe92..3877813 100644
--- a/Foundation/NSAttributedString.swift
+++ b/Foundation/NSAttributedString.swift
@@ -115,7 +115,7 @@
                 attributesInRange = attributes(at: currentIndex, longestEffectiveRange: &attributesEffectiveRange, in: enumerationRange)
             }
             
-            var shouldStop = false
+            var shouldStop: ObjCBool = false
             block(attributesInRange, attributesEffectiveRange, &shouldStop)
             stop.pointee = shouldStop
             
@@ -133,7 +133,7 @@
                 attributeInRange = attribute(attrName, at: currentIndex, longestEffectiveRange: &attributeEffectiveRange, in: enumerationRange)
             }
             
-            var shouldStop = false
+            var shouldStop: ObjCBool = false
             block(attributeInRange, attributeEffectiveRange, &shouldStop)
             stop.pointee = shouldStop
             
@@ -232,10 +232,10 @@
     func _enumerate(in enumerationRange: NSRange, reversed: Bool, using block: (Int, UnsafeMutablePointer<ObjCBool>) -> NSRange) {
         var attributeEnumerationRange = AttributeEnumerationRange(range: enumerationRange, reversed: reversed)
         while attributeEnumerationRange.hasMore {
-            var stop = false
+            var stop: ObjCBool = false
             let effectiveRange = block(attributeEnumerationRange.currentIndex, &stop)
             attributeEnumerationRange.advance(step: effectiveRange.length)
-            if stop {
+            if stop.boolValue {
                 break
             }
         }
diff --git a/Foundation/NSDictionary.swift b/Foundation/NSDictionary.swift
index f331104..8aa981f 100644
--- a/Foundation/NSDictionary.swift
+++ b/Foundation/NSDictionary.swift
@@ -467,11 +467,11 @@
                 lock.lock()
                 var stop = sharedStop
                 lock.unlock()
-                if stop { return }
+                if stop.boolValue { return }
                 
                 closure(keys[idx], objects[idx], &stop)
                 
-                if stop {
+                if stop.boolValue {
                     lock.lock()
                     sharedStop = stop
                     lock.unlock()
diff --git a/Foundation/NSIndexSet.swift b/Foundation/NSIndexSet.swift
index f621657..4a96e8a 100644
--- a/Foundation/NSIndexSet.swift
+++ b/Foundation/NSIndexSet.swift
@@ -396,9 +396,9 @@
         let iteration = withoutActuallyEscaping(block) { (closure: @escaping (P, UnsafeMutablePointer<ObjCBool>) -> R) -> (Int) -> Void in
             return { (rangeIdx) in
                 lock.lock()
-                var stop = sharedStop
+                var stop = ObjCBool(sharedStop)
                 lock.unlock()
-                if stop { return }
+                if stop.boolValue { return }
                 
                 let idx = rangeSequence.index(rangeSequence.startIndex, offsetBy: Int64(rangeIdx))
                 let curRange = rangeSequence[idx]
@@ -407,9 +407,9 @@
                     if intersection.length > 0 {
                         let _ = closure(intersection as! P, &stop)
                     }
-                    if stop {
+                    if stop.boolValue {
                         lock.lock()
-                        sharedStop = stop
+                        sharedStop = stop.boolValue
                         lock.unlock()
                         return
                     }
@@ -426,9 +426,9 @@
                         } else {
                             let _ = closure(idx as! P, &stop)
                         }
-                        if stop {
+                        if stop.boolValue {
                             lock.lock()
-                            sharedStop = stop
+                            sharedStop = stop.boolValue
                             lock.unlock()
                             return
                         }
diff --git a/Foundation/NSPathUtilities.swift b/Foundation/NSPathUtilities.swift
index 0126716..f0b65b4 100644
--- a/Foundation/NSPathUtilities.swift
+++ b/Foundation/NSPathUtilities.swift
@@ -408,9 +408,9 @@
             return false
         }
         
-        var isDirectory = false
+        var isDirectory: ObjCBool = false
         let exists = FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory)
-        return exists && isDirectory
+        return exists && isDirectory.boolValue
     }
     
     internal typealias _FileNamePredicate = (String?) -> Bool
diff --git a/Foundation/NSSet.swift b/Foundation/NSSet.swift
index fdd5b99..939c358 100644
--- a/Foundation/NSSet.swift
+++ b/Foundation/NSSet.swift
@@ -255,7 +255,7 @@
             withUnsafeMutablePointer(to: &stop) { stop in
                 block(obj, stop)
             }
-            if stop {
+            if stop.boolValue {
                 break
             }
         }
diff --git a/Foundation/NSSwiftRuntime.swift b/Foundation/NSSwiftRuntime.swift
index 58a7174..a37839f 100644
--- a/Foundation/NSSwiftRuntime.swift
+++ b/Foundation/NSSwiftRuntime.swift
@@ -24,7 +24,63 @@
 }
 #endif
 
-public typealias ObjCBool = Bool
+/// The Objective-C BOOL type.
+///
+/// On 64-bit iOS, the Objective-C BOOL type is a typedef of C/C++
+/// bool. Elsewhere, it is "signed char". The Clang importer imports it as
+/// ObjCBool.
+@_fixed_layout
+public struct ObjCBool : ExpressibleByBooleanLiteral {
+    #if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
+    // On OS X and 32-bit iOS, Objective-C's BOOL type is a "signed char".
+    var _value: Int8
+
+    init(_ value: Int8) {
+        self._value = value
+    }
+
+    public init(_ value: Bool) {
+        self._value = value ? 1 : 0
+    }
+
+    #else
+    // Everywhere else it is C/C++'s "Bool"
+    var _value: Bool
+
+    public init(_ value: Bool) {
+        self._value = value
+    }
+    #endif
+
+    /// The value of `self`, expressed as a `Bool`.
+    public var boolValue: Bool {
+        #if os(OSX) || (os(iOS) && (arch(i386) || arch(arm)))
+        return _value != 0
+        #else
+        return _value
+        #endif
+    }
+
+    /// Create an instance initialized to `value`.
+    @_transparent
+    public init(booleanLiteral value: Bool) {
+        self.init(value)
+    }
+}
+
+extension ObjCBool : CustomReflectable {
+    /// Returns a mirror that reflects `self`.
+    public var customMirror: Mirror {
+        return Mirror(reflecting: boolValue)
+    }
+}
+
+extension ObjCBool : CustomStringConvertible {
+    /// A textual representation of `self`.
+    public var description: String {
+        return self.boolValue.description
+    }
+}
 
 internal class __NSCFType : NSObject {
     private var _cfinfo : Int32
diff --git a/Foundation/NSURL.swift b/Foundation/NSURL.swift
index 697c488..a02f49c 100644
--- a/Foundation/NSURL.swift
+++ b/Foundation/NSURL.swift
@@ -309,7 +309,7 @@
 
         let thePath = _standardizedPath(path)
         
-        var isDir : Bool = false
+        var isDir: ObjCBool = false
         if thePath.hasSuffix("/") {
             isDir = true
         } else {
@@ -323,7 +323,7 @@
             let _ = FileManager.default.fileExists(atPath: absolutePath, isDirectory: &isDir)
         }
 
-        self.init(fileURLWithPath: thePath, isDirectory: isDir, relativeTo: baseURL)
+        self.init(fileURLWithPath: thePath, isDirectory: isDir.boolValue, relativeTo: baseURL)
     }
 
     public convenience init(fileURLWithPath path: String, isDirectory isDir: Bool) {
@@ -339,7 +339,7 @@
             thePath = path
         }
 
-        var isDir : Bool = false
+        var isDir: ObjCBool = false
         if thePath.hasSuffix("/") {
             isDir = true
         } else {
@@ -348,7 +348,7 @@
             }
         }
         super.init()
-        _CFURLInitWithFileSystemPathRelativeToBase(_cfObject, thePath._cfObject, kCFURLPOSIXPathStyle, isDir, nil)
+        _CFURLInitWithFileSystemPathRelativeToBase(_cfObject, thePath._cfObject, kCFURLPOSIXPathStyle, isDir.boolValue, nil)
     }
     
     public convenience init(fileURLWithFileSystemRepresentation path: UnsafePointer<Int8>, isDirectory isDir: Bool, relativeTo baseURL: URL?) {
@@ -779,8 +779,8 @@
         var result : URL? = appendingPathComponent(pathComponent, isDirectory: false)
         if !pathComponent.hasSuffix("/") && isFileURL {
             if let urlWithoutDirectory = result {
-                var isDir : Bool = false
-                if FileManager.default.fileExists(atPath: urlWithoutDirectory.path, isDirectory: &isDir) && isDir {
+                var isDir: ObjCBool = false
+                if FileManager.default.fileExists(atPath: urlWithoutDirectory.path, isDirectory: &isDir) && isDir.boolValue {
                     result = self.appendingPathComponent(pathComponent, isDirectory: true)
                 }
             }
@@ -859,14 +859,14 @@
         }
 
         // It might be a responsibility of NSURL(fileURLWithPath:). Check it.
-        var isExistingDirectory = false
+        var isExistingDirectory: ObjCBool = false
         let _ = FileManager.default.fileExists(atPath: resolvedPath, isDirectory: &isExistingDirectory)
 
         if excludeSystemDirs {
             resolvedPath = resolvedPath._tryToRemovePathPrefix("/private") ?? resolvedPath
         }
 
-        if isExistingDirectory && !resolvedPath.hasSuffix("/") {
+        if isExistingDirectory.boolValue && !resolvedPath.hasSuffix("/") {
             resolvedPath += "/"
         }
         
diff --git a/TestFoundation/TestFileManager.swift b/TestFoundation/TestFileManager.swift
index a9cb932..9cc1e3e 100644
--- a/TestFoundation/TestFileManager.swift
+++ b/TestFoundation/TestFileManager.swift
@@ -53,10 +53,10 @@
         // Ensure attempting to create the directory again fails gracefully.
         XCTAssertNil(try? fm.createDirectory(atPath: path, withIntermediateDirectories:false, attributes:nil))
 
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: path, isDirectory: &isDir)
         XCTAssertTrue(exists)
-        XCTAssertTrue(isDir)
+        XCTAssertTrue(isDir.boolValue)
 
         do {
             try fm.removeItem(atPath: path)
@@ -74,10 +74,10 @@
         
         XCTAssertTrue(fm.createFile(atPath: path, contents: Data(), attributes: nil))
         
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: path, isDirectory: &isDir)
         XCTAssertTrue(exists)
-        XCTAssertFalse(isDir)
+        XCTAssertFalse(isDir.boolValue)
         
         do {
             try fm.removeItem(atPath: path)
@@ -467,9 +467,9 @@
         }
         
         func directoryExists(atPath path: String) -> Bool {
-            var isDir = false
+            var isDir: ObjCBool = false
             let exists = fm.fileExists(atPath: path, isDirectory: &isDir)
-            return exists && isDir
+            return exists && isDir.boolValue
         }
         
         func createDirectory(atPath path: String) {
diff --git a/TestFoundation/TestHTTPCookieStorage.swift b/TestFoundation/TestHTTPCookieStorage.swift
index 472e34a..b195a08 100644
--- a/TestFoundation/TestHTTPCookieStorage.swift
+++ b/TestFoundation/TestHTTPCookieStorage.swift
@@ -238,7 +238,7 @@
             destPath = NSHomeDirectory() + "/.local/share" + bundleName + "/.cookies.shared"
         }
         let fm = FileManager.default
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: destPath, isDirectory: &isDir)
         XCTAssertTrue(exists)
         //Test by setting the environmental variable
diff --git a/TestFoundation/TestUtils.swift b/TestFoundation/TestUtils.swift
index b587b36..860e129 100644
--- a/TestFoundation/TestUtils.swift
+++ b/TestFoundation/TestUtils.swift
@@ -41,7 +41,7 @@
                     print(err)
                     return false
                 }
-            } else if !isDir {
+            } else if !isDir.boolValue {
                 return false
             }
             
diff --git a/TestFoundation/XDGTestHelper.swift b/TestFoundation/XDGTestHelper.swift
index bdf58a0..9692199 100644
--- a/TestFoundation/XDGTestHelper.swift
+++ b/TestFoundation/XDGTestHelper.swift
@@ -35,7 +35,7 @@
         storage.setCookie(simpleCookie!)
         let fm = FileManager.default
         let destPath = xdg_data_home! + "/xdgTestHelper/.cookies.shared"
-        var isDir = false
+        var isDir: ObjCBool = false
         let exists = fm.fileExists(atPath: destPath, isDirectory: &isDir) 
         if (!exists) {
             print("Expected cookie path: ", destPath)