Merge pull request #247 from llvm-beanz/swift-4.0-branch-stringref-perf

Swift 4.0 branch stringref perf
diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h
index a53eb60..72763ee 100644
--- a/include/lldb/Target/LanguageRuntime.h
+++ b/include/lldb/Target/LanguageRuntime.h
@@ -164,6 +164,9 @@
   virtual bool GetIRPasses(LLVMUserExpression::IRPasses &custom_passes) {
     return false;
   }
+  
+  static bool
+  IsSymbolAnyRuntimeThunk(lldb::ProcessSP process, Symbol &symbol);
 
 protected:
   //------------------------------------------------------------------
diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h
index 0a45ae1..329eb65 100644
--- a/include/lldb/Target/Thread.h
+++ b/include/lldb/Target/Thread.h
@@ -777,6 +777,13 @@
       LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
       LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
 
+  virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRangeNoShouldStop(
+      bool abort_other_plans, const AddressRange &range,
+      const SymbolContext &addr_context, const char *step_in_target,
+      lldb::RunMode stop_other_threads,
+      LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate,
+      LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate);
+
   // Helper function that takes a LineEntry to step, insted of an AddressRange.
   // This may combine multiple
   // LineEntries of the same source line number to step over a longer address
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/simple/Makefile b/packages/Python/lldbsuite/test/functionalities/mtc/simple/Makefile
new file mode 100644
index 0000000..5665652
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/simple/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+OBJC_SOURCES := main.m
+LDFLAGS = $(CFLAGS) -lobjc -framework Foundation -framework AppKit
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/simple/TestMTCSimple.py b/packages/Python/lldbsuite/test/functionalities/mtc/simple/TestMTCSimple.py
new file mode 100644
index 0000000..6a779ec
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/simple/TestMTCSimple.py
@@ -0,0 +1,57 @@
+"""
+Tests basic Main Thread Checker support (detecting a main-thread-only violation).
+"""
+
+import os
+import time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbplatformutil import *
+import json
+
+
+class MTCSimpleTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    def test(self):
+        self.mtc_dylib_path = findMainThreadCheckerDylib()
+        if self.mtc_dylib_path == "":
+            self.skipTest("This test requires libMainThreadChecker.dylib.")
+
+        self.build()
+        self.mtc_tests()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    def mtc_tests(self):
+        # Load the test
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.expect("file " + exe, patterns=["Current executable set to .*a.out"])
+
+        self.runCmd("env DYLD_INSERT_LIBRARIES=%s" % self.mtc_dylib_path)
+        self.runCmd("run")
+
+        process = self.dbg.GetSelectedTarget().process
+        thread = process.GetSelectedThread()
+        frame = thread.GetSelectedFrame()
+
+        self.expect("thread info", substrs=['stop reason = -[NSView superview] must be used from main thread only'])
+
+        self.expect(
+            "thread info -s",
+            substrs=["instrumentation_class", "api_name", "class_name", "selector", "description"])
+        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonInstrumentation)
+        output_lines = self.res.GetOutput().split('\n')
+        json_line = '\n'.join(output_lines[2:])
+        data = json.loads(json_line)
+        self.assertEqual(data["instrumentation_class"], "MainThreadChecker")
+        self.assertEqual(data["api_name"], "-[NSView superview]")
+        self.assertEqual(data["class_name"], "NSView")
+        self.assertEqual(data["selector"], "superview")
+        self.assertEqual(data["description"], "-[NSView superview] must be used from main thread only")
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/simple/main.m b/packages/Python/lldbsuite/test/functionalities/mtc/simple/main.m
new file mode 100644
index 0000000..651347c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/simple/main.m
@@ -0,0 +1,15 @@
+#import <Foundation/Foundation.h>
+#import <AppKit/AppKit.h>
+
+int main() {
+  NSView *view = [[NSView alloc] init];
+  dispatch_group_t g = dispatch_group_create();
+  dispatch_group_enter(g);
+  [NSThread detachNewThreadWithBlock:^{
+    @autoreleasepool {
+      [view superview];
+    }
+    dispatch_group_leave(g);
+  }];
+  dispatch_group_wait(g, DISPATCH_TIME_FOREVER);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/Makefile b/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/Makefile
new file mode 100644
index 0000000..5af7875
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../make
+SWIFT_SOURCES := main.swift
+TRIPLE_SWIFTFLAGS := -target x86_64-apple-macosx10.12
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/TestMTCSwiftProperty.py b/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/TestMTCSwiftProperty.py
new file mode 100644
index 0000000..307325a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/TestMTCSwiftProperty.py
@@ -0,0 +1,57 @@
+"""
+Tests Main Thread Checker support on Swift properties.
+"""
+
+import os
+import time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbplatformutil import *
+import json
+
+
+class MTCSwiftPropertyTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    def test(self):
+        self.mtc_dylib_path = findMainThreadCheckerDylib()
+        if self.mtc_dylib_path == "":
+            self.skipTest("This test requires libMainThreadChecker.dylib.")
+
+        self.build()
+        self.mtc_tests()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    def mtc_tests(self):
+        # Load the test
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.expect("file " + exe, patterns=["Current executable set to .*a.out"])
+
+        self.runCmd("env DYLD_INSERT_LIBRARIES=%s" % self.mtc_dylib_path)
+        self.runCmd("run")
+
+        process = self.dbg.GetSelectedTarget().process
+        thread = process.GetSelectedThread()
+        frame = thread.GetSelectedFrame()
+
+        self.expect("thread info", substrs=['stop reason = NSView.superview must be used from main thread only'])
+
+        self.expect(
+            "thread info -s",
+            substrs=["instrumentation_class", "api_name", "class_name", "selector", "description"])
+        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonInstrumentation)
+        output_lines = self.res.GetOutput().split('\n')
+        json_line = '\n'.join(output_lines[2:])
+        data = json.loads(json_line)
+        self.assertEqual(data["instrumentation_class"], "MainThreadChecker")
+        self.assertEqual(data["api_name"], "NSView.superview")
+        self.assertEqual(data["class_name"], "NSView")
+        self.assertEqual(data["selector"], "superview")
+        self.assertEqual(data["description"], "NSView.superview must be used from main thread only")
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/main.swift b/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/main.swift
new file mode 100644
index 0000000..950b9c2
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/swift-property/main.swift
@@ -0,0 +1,25 @@
+// main.swift
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+// -----------------------------------------------------------------------------
+
+import Foundation
+import AppKit
+
+let view = NSView()
+let g = DispatchGroup()
+g.enter()
+Thread.detachNewThread {
+  autoreleasepool {
+    let _ = view.superview
+  }
+  g.leave()
+}
+g.wait()
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/swift/Makefile b/packages/Python/lldbsuite/test/functionalities/mtc/swift/Makefile
new file mode 100644
index 0000000..5af7875
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/swift/Makefile
@@ -0,0 +1,4 @@
+LEVEL = ../../../make
+SWIFT_SOURCES := main.swift
+TRIPLE_SWIFTFLAGS := -target x86_64-apple-macosx10.12
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/swift/TestMTCSwift.py b/packages/Python/lldbsuite/test/functionalities/mtc/swift/TestMTCSwift.py
new file mode 100644
index 0000000..6def887
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/swift/TestMTCSwift.py
@@ -0,0 +1,57 @@
+"""
+Tests Main Thread Checker support on Swift code.
+"""
+
+import os
+import time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbplatformutil import *
+import json
+
+
+class MTCSwiftTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessDarwin
+    def test(self):
+        self.mtc_dylib_path = findMainThreadCheckerDylib()
+        if self.mtc_dylib_path == "":
+            self.skipTest("This test requires libMainThreadChecker.dylib.")
+
+        self.build()
+        self.mtc_tests()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+
+    def mtc_tests(self):
+        # Load the test
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.expect("file " + exe, patterns=["Current executable set to .*a.out"])
+
+        self.runCmd("env DYLD_INSERT_LIBRARIES=%s" % self.mtc_dylib_path)
+        self.runCmd("run")
+
+        process = self.dbg.GetSelectedTarget().process
+        thread = process.GetSelectedThread()
+        frame = thread.GetSelectedFrame()
+
+        self.expect("thread info", substrs=['stop reason = NSView.removeFromSuperview() must be used from main thread only'])
+
+        self.expect(
+            "thread info -s",
+            substrs=["instrumentation_class", "api_name", "class_name", "selector", "description"])
+        self.assertEqual(thread.GetStopReason(), lldb.eStopReasonInstrumentation)
+        output_lines = self.res.GetOutput().split('\n')
+        json_line = '\n'.join(output_lines[2:])
+        data = json.loads(json_line)
+        self.assertEqual(data["instrumentation_class"], "MainThreadChecker")
+        self.assertEqual(data["api_name"], "NSView.removeFromSuperview()")
+        self.assertEqual(data["class_name"], "NSView")
+        self.assertEqual(data["selector"], "removeFromSuperview")
+        self.assertEqual(data["description"], "NSView.removeFromSuperview() must be used from main thread only")
diff --git a/packages/Python/lldbsuite/test/functionalities/mtc/swift/main.swift b/packages/Python/lldbsuite/test/functionalities/mtc/swift/main.swift
new file mode 100644
index 0000000..f9b4b47
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/mtc/swift/main.swift
@@ -0,0 +1,25 @@
+// main.swift
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+// -----------------------------------------------------------------------------
+
+import Foundation
+import AppKit
+
+let view = NSView()
+let g = DispatchGroup()
+g.enter()
+Thread.detachNewThread {
+  autoreleasepool {
+    view.removeFromSuperview()
+  }
+  g.leave()
+}
+g.wait()
diff --git a/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/Makefile b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/Makefile
new file mode 100644
index 0000000..61b99a1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/Makefile
@@ -0,0 +1,8 @@
+LEVEL = ../../../make
+
+DYLIB_NAME := swiftCore
+DYLIB_CXX_SOURCES := library.cpp
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/TestABIv2.py b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/TestABIv2.py
new file mode 100644
index 0000000..a46f9ff
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/TestABIv2.py
@@ -0,0 +1,85 @@
+# TestABIv2.py
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+# Licensed under Apache License v2.0 with Runtime Library Exception
+#
+# See https://swift.org/LICENSE.txt for license information
+# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+#
+# ------------------------------------------------------------------------------
+"""
+Test Swift Runtime Reporting ABI v2.
+"""
+import lldb
+import lldbsuite.test.decorators as decorators
+import lldbsuite.test.lldbtest as lldbtest
+import lldbsuite.test.lldbutil as lldbutil
+import os
+import unittest2
+import json
+
+
+class SwiftRuntimeReportingABIv2TestCase(lldbtest.TestBase):
+
+    mydir = lldbtest.TestBase.compute_mydir(__file__)
+
+    @decorators.swiftTest
+    @decorators.skipIfLinux
+    def test_swift_runtime_reporting(self):
+        self.build()
+        self.do_test()
+
+    def setUp(self):
+        lldbtest.TestBase.setUp(self)
+
+    def do_test(self):
+        exe_name = "a.out"
+        exe = os.path.join(os.getcwd(), exe_name)
+
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, lldbtest.VALID_TARGET)
+
+        self.runCmd("run")
+
+        self.expect("thread list",
+                    substrs=['stopped', 'stop reason = custom error message'])
+
+        self.assertEqual(
+            self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),
+            lldb.eStopReasonInstrumentation)
+
+        self.expect("thread info -s",
+            substrs=["instrumentation_class", "issue_type", "description"])
+
+        output_lines = self.res.GetOutput().split('\n')
+        json_line = '\n'.join(output_lines[2:])
+        data = json.loads(json_line)
+        self.assertEqual(data["instrumentation_class"], "SwiftRuntimeReporting")
+        self.assertEqual(data["issue_type"], "my-error")
+        self.assertEqual(data["memory_address"], 0)
+        self.assertEqual(data["description"], "custom error message")
+
+        self.assertEqual(len(data["notes"]), 3)
+        self.assertEqual(data["notes"][0]["description"], "note 1")
+        self.assertEqual(data["notes"][1]["description"], "note 2")
+        self.assertEqual(data["notes"][2]["description"], "note 3")
+
+        self.assertEqual(len(data["notes"][0]["fixits"]), 0)
+        self.assertEqual(len(data["notes"][1]["fixits"]), 0)
+        self.assertEqual(len(data["notes"][2]["fixits"]), 0)
+
+        self.assertEqual(len(data["fixits"]), 2)
+        self.assertEqual(data["fixits"][0]["filename"], "filename1")
+        self.assertEqual(data["fixits"][0]["start_line"], 42)
+        self.assertEqual(data["fixits"][0]["start_col"], 1)
+        self.assertEqual(data["fixits"][0]["end_line"], 43)
+        self.assertEqual(data["fixits"][0]["end_col"], 2)
+        self.assertEqual(data["fixits"][0]["replacement"], "replacement1")
+        self.assertEqual(data["fixits"][1]["filename"], "filename2")
+        self.assertEqual(data["fixits"][1]["start_line"], 44)
+        self.assertEqual(data["fixits"][1]["start_col"], 3)
+        self.assertEqual(data["fixits"][1]["end_line"], 45)
+        self.assertEqual(data["fixits"][1]["end_col"], 4)
+        self.assertEqual(data["fixits"][1]["replacement"], "replacement2")
diff --git a/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/library.cpp b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/library.cpp
new file mode 100644
index 0000000..4706776
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/library.cpp
@@ -0,0 +1,16 @@
+// library.cpp
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+// -----------------------------------------------------------------------------
+
+#import "library.h"
+
+extern "C"
+void _swift_runtime_on_report(uintptr_t flags, const char *message, RuntimeErrorDetails *details) { }
diff --git a/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/library.h b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/library.h
new file mode 100644
index 0000000..cc97819
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/library.h
@@ -0,0 +1,59 @@
+// library.h
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+// -----------------------------------------------------------------------------
+
+// From swift's include/swift/Runtime/Debug.h file.
+struct RuntimeErrorDetails {
+  uintptr_t version;
+  const char *errorType;
+  const char *currentStackDescription;
+  uintptr_t framesToSkip;
+  void *memoryAddress;
+
+  struct Thread {
+    const char *description;
+    uint64_t threadID;
+    uintptr_t numFrames;
+    void **frames;
+  };
+
+  uintptr_t numExtraThreads;
+  Thread *threads;
+
+  struct FixIt {
+    const char *filename;
+    uintptr_t startLine;
+    uintptr_t startColumn;
+    uintptr_t endLine;
+    uintptr_t endColumn;
+    const char *replacementText;
+  };
+
+  struct Note {
+    const char *description;
+    uintptr_t numFixIts;
+    FixIt *fixIts;
+  };
+
+  uintptr_t numFixIts;
+  FixIt *fixIts;
+
+  uintptr_t numNotes;
+  Note *notes;
+};
+
+enum: uintptr_t {
+  RuntimeErrorFlagNone = 0,
+  RuntimeErrorFlagFatal = 1 << 0
+};
+
+extern "C"
+void _swift_runtime_on_report(uintptr_t flags, const char *message, RuntimeErrorDetails *details);
diff --git a/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/main.cpp b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/main.cpp
new file mode 100644
index 0000000..7aa5e6a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/swift-runtime-reporting/abi-v2/main.cpp
@@ -0,0 +1,36 @@
+// main.cpp
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+// -----------------------------------------------------------------------------
+
+#import "library.h"
+
+int main() {
+  RuntimeErrorDetails::Note notes[] = {
+      { .description = "note 1" },
+      { .description = "note 2" },
+      { .description = "note 3" },
+  };
+  RuntimeErrorDetails::FixIt fixits[] = {
+    { .filename = "filename1", .startLine = 42, .startColumn = 1,
+      .endLine = 43, .endColumn = 2, .replacementText = "replacement1" },
+    { .filename = "filename2", .startLine = 44, .startColumn = 3,
+      .endLine = 45, .endColumn = 4, .replacementText = "replacement2" }
+  };
+  RuntimeErrorDetails details = {
+    .version = 2,
+    .errorType = "my-error",
+    .notes = &notes[0],
+    .numNotes = 3,
+    .fixIts = &fixits[0],
+    .numFixIts = 2
+  };
+  _swift_runtime_on_report(RuntimeErrorFlagNone, "custom error message", &details);
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/Makefile b/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/Makefile
new file mode 100644
index 0000000..6e7d19b
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/Makefile
@@ -0,0 +1,6 @@
+LEVEL = ../../../make
+
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -fsanitize=undefined -g
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/TestUbsanUserExpression.py b/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/TestUbsanUserExpression.py
new file mode 100644
index 0000000..a5e5f57
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/TestUbsanUserExpression.py
@@ -0,0 +1,49 @@
+"""
+Test that hitting a UBSan issue while running user expression doesn't break the evaluation.
+"""
+
+import os
+import time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+
+class UbsanUserExpressionTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipUnlessUndefinedBehaviorSanitizer
+    def test(self):
+        self.build()
+        self.ubsan_tests()
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        self.line_breakpoint = line_number('main.c', '// breakpoint line')
+
+    def ubsan_tests(self):
+        # Load the test
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.expect(
+            "file " + exe,
+            patterns=["Current executable set to .*a.out"])
+
+        self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint)
+
+        self.runCmd("run")
+
+        process = self.dbg.GetSelectedTarget().process
+        thread = process.GetSelectedThread()
+        frame = thread.GetSelectedFrame()
+
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped', 'stop reason = breakpoint'])
+
+        self.expect("p foo()", substrs=["(int) $0 = 42"])
+
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+                    substrs=['stopped', 'stop reason = breakpoint'])
diff --git a/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/main.c b/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/main.c
new file mode 100644
index 0000000..4786aaa
--- /dev/null
+++ b/packages/Python/lldbsuite/test/functionalities/ubsan/user-expression/main.c
@@ -0,0 +1,9 @@
+int foo() {
+  int data[4];
+  int x = *(int *)(((char *)&data[0]) + 2);
+  return 42;
+}
+
+int main() {
+  return 0; // breakpoint line
+}
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
index c74452f..46bd384 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/hello_watchpoint/TestMyFirstWatchpoint.py
@@ -39,6 +39,9 @@
     @expectedFailureAll(
         oslist=["windows"],
         bugnumber="llvm.org/pr24446: WINDOWS XFAIL TRIAGE - Watchpoints not supported on Windows")
+    @expectedFailureAll(
+        oslist=["linux"],
+        bugnumber="https://bugs.swift.org/browse/SR-5555 MyFirstWatchpoint test fails on Ubuntu 16.04")
     def test_hello_watchpoint_using_watchpoint_set(self):
         """Test a simple sequence of watchpoint creation and watchpoint hit."""
         self.build(dictionary=self.d)
diff --git a/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py b/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
index 96c5a33..77e5a8b 100644
--- a/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
+++ b/packages/Python/lldbsuite/test/lang/objc/objc-new-syntax/TestObjCNewSyntax.py
@@ -121,6 +121,8 @@
             '7.0.0'])
     @skipIf(macos_version=["<", "10.12"])
     @expectedFailureAll(archs=["i[3-6]86"])
+    @expectedFailureAll(debug_info="gmodules",
+                        bugnumber="rdar://problem/32777981")
     def test_update_dictionary(self):
         self.runToBreakpoint()
 
@@ -163,6 +165,8 @@
             '7.0.0'])
     @skipIf(macos_version=["<", "10.12"])
     @expectedFailureAll(archs=["i[3-6]86"])
+    @expectedFailureAll(debug_info="gmodules",
+                        bugnumber="rdar://problem/32777981")
     def test_dictionary_literal(self):
         self.runToBreakpoint()
 
diff --git a/packages/Python/lldbsuite/test/lang/swift/let_int/TestSwiftLetInt.py b/packages/Python/lldbsuite/test/lang/swift/let_int/TestSwiftLetInt.py
index ad8d706..fba2ea4 100644
--- a/packages/Python/lldbsuite/test/lang/swift/let_int/TestSwiftLetInt.py
+++ b/packages/Python/lldbsuite/test/lang/swift/let_int/TestSwiftLetInt.py
@@ -68,6 +68,16 @@
         lldbutil.check_variable(self, let, False, value="10")
         lldbutil.check_variable(self, var, False, value="10")
 
+        get_arguments = False
+        get_locals = True
+        get_statics = False
+        get_in_scope_only = True
+        local_vars = self.frame.GetVariables(get_arguments, get_locals,
+                                             get_statics, get_in_scope_only)
+        self.assertTrue(local_vars.GetFirstValueByName("x").IsValid())
+        self.assertTrue(local_vars.GetFirstValueByName("y").IsValid())
+        self.assertTrue(not local_vars.GetFirstValueByName("z").IsValid())
+
 if __name__ == '__main__':
     import atexit
     lldb.SBDebugger.Initialize()
diff --git a/packages/Python/lldbsuite/test/lang/swift/let_int/main.swift b/packages/Python/lldbsuite/test/lang/swift/let_int/main.swift
index f7dd177..81c6acc 100644
--- a/packages/Python/lldbsuite/test/lang/swift/let_int/main.swift
+++ b/packages/Python/lldbsuite/test/lang/swift/let_int/main.swift
@@ -9,10 +9,13 @@
 // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
 //
 // -----------------------------------------------------------------------------
+
+let z = 10
+
 func main() {
   let x = 10
   var y = 10
-  print(x+y) // Set breakpoint here
+  print(x+y+z) // Set breakpoint here
 }
 
 main()
diff --git a/packages/Python/lldbsuite/test/lang/swift/stepping/TestSwiftStepping.py b/packages/Python/lldbsuite/test/lang/swift/stepping/TestSwiftStepping.py
index 7aa8e50..55c58c8 100644
--- a/packages/Python/lldbsuite/test/lang/swift/stepping/TestSwiftStepping.py
+++ b/packages/Python/lldbsuite/test/lang/swift/stepping/TestSwiftStepping.py
@@ -26,7 +26,6 @@
     mydir = lldbtest.TestBase.compute_mydir(__file__)
 
     @decorators.swiftTest
-    @decorators.expectedFailureAll(bugnumber="rdar://31515444")
     def test_swift_stepping(self):
         """Tests that we can step reliably in swift code."""
         self.build()
@@ -289,11 +288,12 @@
         # Step out of the protocol function, one step out should also
         # get us past any dispatch thunk.
         thread.StepOut()
-        self.hit_correct_line(thread, "indirect.protocol_func(20)")
-
+        stop_on_caller = self.hit_correct_line(thread, "indirect.protocol_func(20)", False)
+        
         # And one step over is necessary because step out doesn't
         # finish off the line.
-        thread.StepOver()
+        if stop_on_caller:
+            thread.StepOver()
         self.hit_correct_line(thread, "doSomethingWithFunction(cd_maker, 10)")
 
         thread.StepInto()
diff --git a/packages/Python/lldbsuite/test/lang/swift/variables/bool/Makefile b/packages/Python/lldbsuite/test/lang/swift/variables/bool/Makefile
new file mode 100644
index 0000000..f9ac017
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/swift/variables/bool/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../../make
+
+SWIFT_SOURCES := main.swift
+
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/swift/variables/bool/TestSwiftBool.py b/packages/Python/lldbsuite/test/lang/swift/variables/bool/TestSwiftBool.py
new file mode 100644
index 0000000..36fd40c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/swift/variables/bool/TestSwiftBool.py
@@ -0,0 +1,84 @@
+# TestSwiftBool.py
+#
+# This source file is part of the Swift.org open source project
+#
+# Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+# Licensed under Apache License v2.0 with Runtime Library Exception
+#
+# See https://swift.org/LICENSE.txt for license information
+# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+#
+# ------------------------------------------------------------------------------
+"""
+Test that we can inspect Swift Bools - they are 8 bit entities with only the
+LSB significant.  Make sure that works.
+"""
+import lldb
+from lldbsuite.test.lldbtest import *
+import lldbsuite.test.decorators as decorators
+import lldbsuite.test.lldbutil as lldbutil
+import unittest2
+
+
+class TestSwiftBool(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @decorators.swiftTest
+    def test_swift_bool(self):
+        """Test that we can inspect various Swift bools"""
+        self.build()
+        self.do_test()
+
+    def setUp(self):
+        TestBase.setUp(self)
+        self.main_source = "main.swift"
+        self.main_source_spec = lldb.SBFileSpec(self.main_source)
+
+    def do_test(self):
+        """Tests that we can break and display simple types"""
+        exe_name = "a.out"
+        exe = os.path.join(os.getcwd(), exe_name)
+
+        # Create the target
+        target = self.dbg.CreateTarget(exe)
+        self.assertTrue(target, VALID_TARGET)
+
+        # Set the breakpoints
+        breakpoint = target.BreakpointCreateBySourceRegex(
+            'Set breakpoint here', self.main_source_spec)
+        self.assertTrue(breakpoint.GetNumLocations() > 0, VALID_BREAKPOINT)
+
+        # Launch the process, and do not stop at the entry point.
+        process = target.LaunchSimple(None, None, os.getcwd())
+
+        self.assertTrue(process, PROCESS_IS_VALID)
+
+        # Frame #0 should be at our breakpoint.
+        threads = lldbutil.get_threads_stopped_at_breakpoint(
+            process, breakpoint)
+
+        self.assertTrue(len(threads) == 1)
+        thread = threads[0]
+        
+        frame = thread.frames[0]
+        self.assertTrue(frame.IsValid(), "Couldn't get a frame.")
+        
+        true_vars = ["reg_true", "odd_true", "odd_true_works", "odd_false_works"]
+        for name in true_vars:
+            var = frame.FindVariable(name)
+            summary = var.GetSummary()
+            self.assertTrue(summary == "true", "%s should be true, was: %s"%(name, summary))
+
+        false_vars = ["reg_false", "odd_false"]
+        for name in false_vars:
+            var = frame.FindVariable(name)
+            summary = var.GetSummary()
+            self.assertTrue(summary == "false", "%s should be false, was: %s"%(name, summary))
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lldb.SBDebugger.Terminate)
+    unittest2.main()
diff --git a/packages/Python/lldbsuite/test/lang/swift/variables/bool/main.swift b/packages/Python/lldbsuite/test/lang/swift/variables/bool/main.swift
new file mode 100644
index 0000000..48901e1
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/swift/variables/bool/main.swift
@@ -0,0 +1,29 @@
+// main.swift
+//
+// This source file is part of the Swift.org open source project
+//
+// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
+// Licensed under Apache License v2.0 with Runtime Library Exception
+//
+// See https://swift.org/LICENSE.txt for license information
+// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
+//
+// -----------------------------------------------------------------------------
+
+func main() -> Int {
+    let short_five : Int8 = 5
+    let short_four : Int8 = 4
+
+    var reg_true : Bool   = true
+    var reg_false : Bool  = false
+    var odd_true : Bool   = unsafeBitCast(short_five, to: Bool.self)
+    var odd_false : Bool  = unsafeBitCast(short_four, to: Bool.self)
+
+    var odd_true_works = reg_true == odd_true
+    var odd_false_works = reg_false == odd_false
+
+    print("stop here") // Set breakpoint here
+    return 0
+}
+
+main()
diff --git a/packages/Python/lldbsuite/test/lang/swift/variables/inout/TestInOutVariables.py b/packages/Python/lldbsuite/test/lang/swift/variables/inout/TestInOutVariables.py
index 5de59eb..fbbe01f 100644
--- a/packages/Python/lldbsuite/test/lang/swift/variables/inout/TestInOutVariables.py
+++ b/packages/Python/lldbsuite/test/lang/swift/variables/inout/TestInOutVariables.py
@@ -100,6 +100,9 @@
                 lldb.eDynamicCanRunTarget)
             message_end = "from FindVariable"
 
+            # Make sure we can get the object description without crashing
+            _ = self.frame.FindVariable("x").description
+
         self.assertTrue(x.IsValid(), "did not find x %s" % (message_end))
         self.assertTrue(
             x.GetNumChildren() == 1,
diff --git a/packages/Python/lldbsuite/test/lang/swift/variables/protocol/main.swift b/packages/Python/lldbsuite/test/lang/swift/variables/protocol/main.swift
index a3c0a28..767bee0 100644
--- a/packages/Python/lldbsuite/test/lang/swift/variables/protocol/main.swift
+++ b/packages/Python/lldbsuite/test/lang/swift/variables/protocol/main.swift
@@ -46,14 +46,18 @@
     
 }
 
-func main() -> Int {
-    
-    var loc2d : protocol<PointUtils> = Point2D(1.25, 2.5)
-    var loc3d : protocol<PointUtils> = Point3D(1.25, 2.5, 1.25)
-    var sum2d = loc2d.sumOfCoordinates()
-    var sum3d = loc3d.sumOfCoordinates()
+func takes_protocol(_ loc2d : PointUtils,_ loc3d : PointUtils) {
+    let sum2d = loc2d.sumOfCoordinates()
+    let sum3d = loc3d.sumOfCoordinates()
     print("hello \(sum2d) \(sum3d)") // Set breakpoint here
-    return 0
+}
+
+func main() {
+
+    var loc2d = Point2D(1.25, 2.5)
+    var loc3d = Point3D(1.25, 2.5, 1.25)
+
+    takes_protocol (loc2d, loc3d)
 }
 
 main()
diff --git a/packages/Python/lldbsuite/test/lldbplatformutil.py b/packages/Python/lldbsuite/test/lldbplatformutil.py
index 0d5254b..0673e7d 100644
--- a/packages/Python/lldbsuite/test/lldbplatformutil.py
+++ b/packages/Python/lldbsuite/test/lldbplatformutil.py
@@ -8,6 +8,7 @@
 import re
 import subprocess
 import sys
+import os
 
 # Third-party modules
 import six
@@ -140,6 +141,19 @@
     return getPlatform() in getDarwinOSTriples()
 
 
+def findMainThreadCheckerDylib():
+    if not platformIsDarwin():
+        return ""
+
+    with os.popen('xcode-select -p') as output:
+        xcode_developer_path = output.read().strip()
+        mtc_dylib_path = '%s/usr/lib/libMainThreadChecker.dylib' % xcode_developer_path
+        if os.path.isfile(mtc_dylib_path):
+            return mtc_dylib_path
+
+    return ""
+
+
 class _PlatformContext(object):
     """Value object class which contains platform-specific options."""
 
diff --git a/packages/Python/lldbsuite/test/repl/breakpoints/TestREPLBreakpoints.py b/packages/Python/lldbsuite/test/repl/breakpoints/TestREPLBreakpoints.py
index d09fc17..3803a38 100644
--- a/packages/Python/lldbsuite/test/repl/breakpoints/TestREPLBreakpoints.py
+++ b/packages/Python/lldbsuite/test/repl/breakpoints/TestREPLBreakpoints.py
@@ -16,12 +16,12 @@
 import unittest2
 import lldb
 import lldbsuite.test.decorators as decorators
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLBreakpointsTestCase (REPLTest):
+class REPLBreakpointsTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     @decorators.swiftTest
     @decorators.no_debug_info_test
diff --git a/packages/Python/lldbsuite/test/repl/closures/TestREPLClosure.py b/packages/Python/lldbsuite/test/repl/closures/TestREPLClosure.py
index e9ddaf9..77b0aff 100644
--- a/packages/Python/lldbsuite/test/repl/closures/TestREPLClosure.py
+++ b/packages/Python/lldbsuite/test/repl/closures/TestREPLClosure.py
@@ -15,12 +15,12 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLClosureTestCase (REPLTest):
+class REPLClosureTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     def doTest(self):
         self.command(
diff --git a/packages/Python/lldbsuite/test/repl/dictionary/TestREPLDictionary.py b/packages/Python/lldbsuite/test/repl/dictionary/TestREPLDictionary.py
index 7373f76..51f07e3 100644
--- a/packages/Python/lldbsuite/test/repl/dictionary/TestREPLDictionary.py
+++ b/packages/Python/lldbsuite/test/repl/dictionary/TestREPLDictionary.py
@@ -15,13 +15,13 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 import lldbsuite.test.decorators as decorators
 
 
-class REPLDictionaryTestCase (REPLTest):
+class REPLDictionaryTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     @decorators.swiftTest
     @decorators.no_debug_info_test
@@ -29,7 +29,7 @@
         oslist=['linux'],
         bugnumber="bugs.swift.org/SR-843")
     def testREPL(self):
-        REPLTest.testREPL(self)
+        lldbrepl.REPLTest.testREPL(self)
 
     def doTest(self):
         self.sendline('[1:2, 2:3, 3:9]')
diff --git a/packages/Python/lldbsuite/test/repl/dyntype/TestREPLDynamicType.py b/packages/Python/lldbsuite/test/repl/dyntype/TestREPLDynamicType.py
index 8bb86e5..7f96a8a 100644
--- a/packages/Python/lldbsuite/test/repl/dyntype/TestREPLDynamicType.py
+++ b/packages/Python/lldbsuite/test/repl/dyntype/TestREPLDynamicType.py
@@ -15,12 +15,12 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLDynamicTypeTestCase (REPLTest):
+class REPLDynamicTypeTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     def doTest(self):
         self.command('type(of: 1)', patterns=['\\$R0: Int.Type = Int'])
diff --git a/packages/Python/lldbsuite/test/repl/func_definition/TestREPLFunctionDefinition.py b/packages/Python/lldbsuite/test/repl/func_definition/TestREPLFunctionDefinition.py
index 87feb43..a25cfa6 100644
--- a/packages/Python/lldbsuite/test/repl/func_definition/TestREPLFunctionDefinition.py
+++ b/packages/Python/lldbsuite/test/repl/func_definition/TestREPLFunctionDefinition.py
@@ -15,12 +15,12 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLFuncDefinitionTestCase (REPLTest):
+class REPLFuncDefinitionTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     def doTest(self):
         self.command(
diff --git a/packages/Python/lldbsuite/test/repl/int_vars/TestREPLIntVars.py b/packages/Python/lldbsuite/test/repl/int_vars/TestREPLIntVars.py
index f3f016f..cdf8bd3 100644
--- a/packages/Python/lldbsuite/test/repl/int_vars/TestREPLIntVars.py
+++ b/packages/Python/lldbsuite/test/repl/int_vars/TestREPLIntVars.py
@@ -16,12 +16,12 @@
 import unittest2
 import lldb
 import lldbsuite.test.decorators as decorators
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLIntVarsTestCase (REPLTest):
+class REPLIntVarsTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     @decorators.swiftTest
     @decorators.no_debug_info_test
@@ -29,7 +29,7 @@
         oslist=["linux"],
         bugnumber="rdar://23081322")
     def testREPL(self):
-        REPLTest.testREPL(self)
+        lldbrepl.REPLTest.testREPL(self)
 
     def doTest(self):
         self.command('3 + 2', patterns=['\\$R0: Int = 5'])
diff --git a/packages/Python/lldbsuite/test/repl/multilevelarrays/TestMultilevelArrays.py b/packages/Python/lldbsuite/test/repl/multilevelarrays/TestMultilevelArrays.py
index d018b28..9e9dba4 100644
--- a/packages/Python/lldbsuite/test/repl/multilevelarrays/TestMultilevelArrays.py
+++ b/packages/Python/lldbsuite/test/repl/multilevelarrays/TestMultilevelArrays.py
@@ -15,12 +15,12 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLNestedArrayTestCase (REPLTest):
+class REPLNestedArrayTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     def doTest(self):
         self.command('[[1,2,3,4],[1,2,3],[1,2],[],[1]]', patterns=[
diff --git a/packages/Python/lldbsuite/test/repl/nsobject_subclass/TestNSObjectSubclass.py b/packages/Python/lldbsuite/test/repl/nsobject_subclass/TestNSObjectSubclass.py
index 373b825..8a94152 100644
--- a/packages/Python/lldbsuite/test/repl/nsobject_subclass/TestNSObjectSubclass.py
+++ b/packages/Python/lldbsuite/test/repl/nsobject_subclass/TestNSObjectSubclass.py
@@ -15,20 +15,20 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 import lldbsuite.test.decorators as decorators
 import lldbsuite.test.lldbtest as lldbtest
 
 
-class REPLNSObjectSubclassTest (REPLTest):
+class REPLNSObjectSubclassTest (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     @decorators.swiftTest
     @decorators.skipUnlessDarwin
     @decorators.no_debug_info_test
     def testREPL(self):
-        REPLTest.testREPL(self)
+        lldbrepl.REPLTest.testREPL(self)
 
     def doTest(self):
         self.command('import Foundation', timeout=20)
diff --git a/packages/Python/lldbsuite/test/repl/nsstring/TestREPLNSString.py b/packages/Python/lldbsuite/test/repl/nsstring/TestREPLNSString.py
index c7035cf..a637d1f 100644
--- a/packages/Python/lldbsuite/test/repl/nsstring/TestREPLNSString.py
+++ b/packages/Python/lldbsuite/test/repl/nsstring/TestREPLNSString.py
@@ -16,18 +16,18 @@
 import unittest2
 import lldb
 import lldbsuite.test.decorators as decorators
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 
 
-class REPLNSStringTestCase (REPLTest):
+class REPLNSStringTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     @decorators.swiftTest
     @decorators.skipUnlessDarwin
     @decorators.no_debug_info_test
     def testREPL(self):
-        REPLTest.testREPL(self)
+        lldbrepl.REPLTest.testREPL(self)
 
     def doTest(self):
         self.command('import Foundation', timeout=20)
diff --git a/packages/Python/lldbsuite/test/repl/quicklookobject/TestREPLQuickLookObject.py b/packages/Python/lldbsuite/test/repl/quicklookobject/TestREPLQuickLookObject.py
index baf729f..2127aab 100644
--- a/packages/Python/lldbsuite/test/repl/quicklookobject/TestREPLQuickLookObject.py
+++ b/packages/Python/lldbsuite/test/repl/quicklookobject/TestREPLQuickLookObject.py
@@ -15,13 +15,13 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 import lldbsuite.test.lldbtest as lldbtest
 
 
-class REPLQuickLookTestCase (REPLTest):
+class REPLQuickLookTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
     def doTest(self):
         self.command(
diff --git a/packages/Python/lldbsuite/test/repl/subclassing/TestREPLSubclassing.py b/packages/Python/lldbsuite/test/repl/subclassing/TestREPLSubclassing.py
index 38618b1..5e92c88 100644
--- a/packages/Python/lldbsuite/test/repl/subclassing/TestREPLSubclassing.py
+++ b/packages/Python/lldbsuite/test/repl/subclassing/TestREPLSubclassing.py
@@ -15,24 +15,21 @@
 import time
 import unittest2
 import lldb
-from lldbsuite.test.lldbrepl import REPLTest, load_tests
+import lldbsuite.test.lldbrepl as lldbrepl
 from lldbsuite.test import decorators
 
 
-class REPLSubclassingTestCase (REPLTest):
+class REPLSubclassingTestCase (lldbrepl.REPLTest):
 
-    mydir = REPLTest.compute_mydir(__file__)
+    mydir = lldbrepl.REPLTest.compute_mydir(__file__)
 
-    @decorators.expectedFailureAll(
-        oslist=["macosx"],
-        bugnumber="rdar://26768714")
     def doTest(self):
         self.command('class A {init(a: Int) {}}')
         self.command(
-            'class B : A {let x: Int; init() { x = 10; super.init(a: x) } }')
+            'class B : A {let x: Int; init() { x = 5 + 5; super.init(a: x) } }')
         self.command('print(B().x)', patterns=['10'])
         self.command(
-            'extension B : CustomStringConvertible { var description:String { return "class B is a subclass of class A"} }')
+            'extension B : CustomStringConvertible { public var description:String { return "class B\(x) is a subclass of class A"} }')
         self.command(
             'print(B())',
-            patterns=['class B is a subclass of class A'])
+            patterns=['class B(10) is a subclass of class A'])
diff --git a/scripts/Xcode/build-llvm.py b/scripts/Xcode/build-llvm.py
index 077abc3..94a6dfb 100755
--- a/scripts/Xcode/build-llvm.py
+++ b/scripts/Xcode/build-llvm.py
@@ -54,6 +54,9 @@
     }
 
 def XCODE_REPOSITORIES():
+    override = repo.get_override()
+    if override:
+        return [process_repo(r) for r in override]
     identifier = repo.identifier()
     if identifier == None:
         return [fallback_repo(n) for n in ["llvm", "clang", "swift", "cmark", "ninja"]]
diff --git a/scripts/Xcode/repo.py b/scripts/Xcode/repo.py
index d6e1aee..355159c 100644
--- a/scripts/Xcode/repo.py
+++ b/scripts/Xcode/repo.py
@@ -20,6 +20,17 @@
 		pass
 	return None
 
+def get_override():
+	dir = os.path.dirname(os.path.realpath(__file__))
+	repos_dir = os.path.join(dir, "repos")
+	json_regex = re.compile(r"^.*.json$")
+	override_path = os.path.join(repos_dir, "OVERRIDE")
+	if os.path.isfile(override_path):
+		override_set = json.load(open(override_path))
+		return override_set["repos"]
+        else:
+		return None
+
 def find(identifier):
 	dir = os.path.dirname(os.path.realpath(__file__))
 	repos_dir = os.path.join(dir, "repos")
diff --git a/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp b/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp
index 2bbb2c0..f73b655 100644
--- a/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp
+++ b/source/Plugins/ExpressionParser/Swift/SwiftASTManipulator.cpp
@@ -835,10 +835,16 @@
     virtual bool walkToDeclPre(swift::Decl *decl) {
       if (swift::ValueDecl *value_decl =
               llvm::dyn_cast<swift::ValueDecl>(decl)) {
-        value_decl->overwriteAccessibility(swift::Accessibility::Public);
+        auto access = swift::Accessibility::Public;
+        if (swift::isa<swift::ClassDecl>(value_decl) ||
+            swift::isa<swift::ClassDecl>(value_decl->getDeclContext())) {
+          access = swift::Accessibility::Open;
+        }
+
+        value_decl->overwriteAccessibility(access);
         if (swift::AbstractStorageDecl *var_decl =
                 llvm::dyn_cast<swift::AbstractStorageDecl>(decl))
-          var_decl->overwriteSetterAccessibility(swift::Accessibility::Public);
+          var_decl->overwriteSetterAccessibility(access);
       }
 
       return true;
diff --git a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
index 84e32b7..27761d7 100644
--- a/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
@@ -247,12 +247,16 @@
   AddressSanitizerRuntime *const instance =
       static_cast<AddressSanitizerRuntime *>(baton);
 
+  ProcessSP process_sp = instance->GetProcessSP();
+
+  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+    return false;
+
   StructuredData::ObjectSP report = instance->RetrieveReportData();
   std::string description;
   if (report) {
     description = instance->FormatDescription(report);
   }
-  ProcessSP process_sp = instance->GetProcessSP();
   // Make sure this is the right process
   if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
     ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
diff --git a/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp b/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
index 0283523..54c13f6 100644
--- a/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
@@ -109,12 +109,32 @@
                            swift::DeclVisibilityKind Reason) {
       if (result)
         return; // Take the first result.
-      if (swift::ClassDecl *cls = clang::dyn_cast<swift::ClassDecl>(VD)) {
-        auto funcs = cls->lookupDirect(selectorToLookup, true);
-        if (funcs.size() > 0) {
-          result = funcs.front()->getFullName();
+      swift::ClassDecl *cls = llvm::dyn_cast<swift::ClassDecl>(VD);
+      if (!cls)
+        return;
+      auto funcs = cls->lookupDirect(selectorToLookup, true);
+      if (funcs.size() == 0)
+        return;
+
+      // If the decl is actually an accessor, use the property name instead.
+      swift::AbstractFunctionDecl *decl = funcs.front();
+      if (auto func = llvm::dyn_cast<swift::FuncDecl>(decl)) {
+        swift::DeclContext *funcCtx = func->getParent();
+        // We need to loadAllMembers(), otherwise 'isAccessor' returns false.
+        if (auto extension = llvm::dyn_cast<swift::ExtensionDecl>(funcCtx)) {
+          extension->loadAllMembers();
+        } else if (auto nominal =
+                       llvm::dyn_cast<swift::NominalTypeDecl>(funcCtx)) {
+          nominal->loadAllMembers();
+        }
+
+        if (func->isAccessor()) {
+          result = func->getAccessorStorageDecl()->getFullName();
+          return;
         }
       }
+
+      result = decl->getFullName();
     }
   };
 
@@ -211,7 +231,7 @@
   d->AddStringItem("class_name", className);
   d->AddStringItem("selector", selector);
   d->AddStringItem("description",
-                   apiName + " must be called from main thread only");
+                   apiName + " must be used from main thread only");
   d->AddIntegerItem("tid", thread_sp->GetIndexID());
   d->AddItem("trace", trace_sp);
   return dict_sp;
@@ -233,6 +253,9 @@
       process_sp != context->exe_ctx_ref.GetProcessSP())
     return false;
 
+  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+    return false;
+
   StructuredData::ObjectSP report =
       instance->RetrieveReportData(context->exe_ctx_ref);
 
diff --git a/source/Plugins/InstrumentationRuntime/SwiftRuntimeReporting/SwiftRuntimeReporting.cpp b/source/Plugins/InstrumentationRuntime/SwiftRuntimeReporting/SwiftRuntimeReporting.cpp
index 73e2b43..e0566f5 100644
--- a/source/Plugins/InstrumentationRuntime/SwiftRuntimeReporting/SwiftRuntimeReporting.cpp
+++ b/source/Plugins/InstrumentationRuntime/SwiftRuntimeReporting/SwiftRuntimeReporting.cpp
@@ -181,7 +181,7 @@
   if (num_notes > 16) num_notes = 16;
   addr_t fixits_ptr = process_sp->ReadUnsignedIntegerFromMemory(addr + ptr_size, ptr_size, 0, read_error);
   for (int i = 0; i < num_notes; i++) {
-    int note_struct_stride = 6 * ptr_size;
+    int note_struct_stride = 3 * ptr_size;
     addr_t note_ptr = fixits_ptr + i * note_struct_stride;
 
     std::string note_description;
@@ -340,6 +340,9 @@
       process_sp != context->exe_ctx_ref.GetProcessSP())
     return false;
 
+  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+    return false;
+
   StructuredData::ObjectSP report =
       instance->RetrieveReportData(context->exe_ctx_ref);
 
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
index 9cc3f1a..70dca5b 100644
--- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
@@ -803,6 +803,11 @@
   ThreadSanitizerRuntime *const instance =
       static_cast<ThreadSanitizerRuntime *>(baton);
 
+  ProcessSP process_sp = instance->GetProcessSP();
+
+  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+    return false;
+
   StructuredData::ObjectSP report =
       instance->RetrieveReportData(context->exe_ctx_ref);
   std::string stop_reason_description;
@@ -851,7 +856,6 @@
                                               all_addresses_are_same);
   }
 
-  ProcessSP process_sp = instance->GetProcessSP();
   // Make sure this is the right process
   if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
     ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
diff --git a/source/Plugins/InstrumentationRuntime/UndefinedBehaviorSanitizer/UndefinedBehaviorSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/UndefinedBehaviorSanitizer/UndefinedBehaviorSanitizerRuntime.cpp
index c8e1ce8..09eda21 100644
--- a/source/Plugins/InstrumentationRuntime/UndefinedBehaviorSanitizer/UndefinedBehaviorSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/UndefinedBehaviorSanitizer/UndefinedBehaviorSanitizerRuntime.cpp
@@ -216,6 +216,9 @@
       process_sp != context->exe_ctx_ref.GetProcessSP())
     return false;
 
+  if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+    return false;
+
   StructuredData::ObjectSP report =
       instance->RetrieveReportData(context->exe_ctx_ref);
 
diff --git a/source/Plugins/Language/ObjC/NSArray.cpp b/source/Plugins/Language/ObjC/NSArray.cpp
index 2e2513f..fae0ebc 100644
--- a/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/source/Plugins/Language/ObjC/NSArray.cpp
@@ -160,11 +160,47 @@
   DataDescriptor_64 *m_data_64;
 };
 
-class NSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+class NSArrayMSyntheticFrontEnd_1400 : public NSArrayMSyntheticFrontEnd {
 public:
-  NSArrayISyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+  NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
 
-  ~NSArrayISyntheticFrontEnd() override = default;
+  ~NSArrayMSyntheticFrontEnd_1400() override;
+
+  bool Update() override;
+
+protected:
+  lldb::addr_t GetDataAddress() override;
+
+  uint64_t GetUsedCount() override;
+
+  uint64_t GetOffset() override;
+
+  uint64_t GetSize() override;
+
+private:
+  struct DataDescriptor_32 {
+    uint32_t used;
+    uint32_t offset;
+    uint32_t size;
+    uint32_t list;
+  };
+
+  struct DataDescriptor_64 {
+    uint64_t used;
+    uint64_t offset;
+    uint64_t size;
+    uint64_t list;
+  };
+
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+};
+
+class NSArrayISyntheticFrontEnd_1300 : public SyntheticChildrenFrontEnd {
+public:
+  NSArrayISyntheticFrontEnd_1300(lldb::ValueObjectSP valobj_sp);
+
+  ~NSArrayISyntheticFrontEnd_1300() override = default;
 
   size_t CalculateNumChildren() override;
 
@@ -184,6 +220,45 @@
   CompilerType m_id_type;
 };
 
+class NSArrayISyntheticFrontEnd_1400 : public SyntheticChildrenFrontEnd {
+public:
+  NSArrayISyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp);
+
+  ~NSArrayISyntheticFrontEnd_1400() override;
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  bool MightHaveChildren() override;
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+  ExecutionContextRef m_exe_ctx_ref;
+  uint8_t m_ptr_size;
+
+  struct DataDescriptor_32 {
+    uint32_t used;
+    uint32_t offset;
+    uint32_t size;
+    uint32_t list;
+  };
+
+  struct DataDescriptor_64 {
+    uint64_t used;
+    uint64_t offset;
+    uint64_t size;
+    uint64_t list;
+  };
+
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+  CompilerType m_id_type;
+};
+
 class NSArray0SyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
   NSArray0SyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -257,6 +332,8 @@
   static const ConstString g_NSArray0("__NSArray0");
   static const ConstString g_NSArray1("__NSSingleObjectArrayI");
   static const ConstString g_NSArrayCF("__NSCFArray");
+  static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
+  static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
 
   if (class_name.IsEmpty())
     return false;
@@ -273,6 +350,18 @@
                                                       ptr_size, 0, error);
     if (error.Fail())
       return false;
+  } else if (class_name == g_NSArrayMLegacy) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
+  } else if (class_name == g_NSArrayMImmutable) {
+    Error error;
+    value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
+                                                      ptr_size, 0, error);
+    if (error.Fail())
+      return false;
   } else if (class_name == g_NSArray0) {
     value = 0;
   } else if (class_name == g_NSArray1) {
@@ -332,6 +421,11 @@
     : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
       m_data_64(nullptr) {}
 
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
+    NSArrayMSyntheticFrontEnd_1400(lldb::ValueObjectSP valobj_sp)
+    : NSArrayMSyntheticFrontEnd(valobj_sp), m_data_32(nullptr),
+      m_data_64(nullptr) {}
+
 size_t
 lldb_private::formatters::NSArrayMSyntheticFrontEnd::CalculateNumChildren() {
   return GetUsedCount();
@@ -416,6 +510,37 @@
   return false;
 }
 
+bool lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::Update() {
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  m_ptr_size = 0;
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return false;
+  m_ptr_size = process_sp->GetAddressByteSize();
+  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+  if (m_ptr_size == 4) {
+    m_data_32 = new DataDescriptor_32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+                           error);
+  } else {
+    m_data_64 = new DataDescriptor_64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+                           error);
+  }
+  if (error.Fail())
+    return false;
+  return false;
+}
+
 bool lldb_private::formatters::NSArrayMSyntheticFrontEnd::MightHaveChildren() {
   return true;
 }
@@ -498,7 +623,42 @@
   return m_data_32 ? m_data_32->_size : m_data_64->_size;
 }
 
-lldb_private::formatters::NSArrayISyntheticFrontEnd::NSArrayISyntheticFrontEnd(
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::
+    ~NSArrayMSyntheticFrontEnd_1400() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+}
+
+lldb::addr_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetDataAddress() {
+  if (!m_data_32 && !m_data_64)
+    return LLDB_INVALID_ADDRESS;
+  return m_data_32 ? m_data_32->list : m_data_64->list;
+}
+
+uint64_t
+lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetUsedCount() {
+  if (!m_data_32 && !m_data_64)
+    return 0;
+  return m_data_32 ? m_data_32->used : m_data_64->used;
+}
+
+uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetOffset() {
+  if (!m_data_32 && !m_data_64)
+    return 0;
+  return m_data_32 ? m_data_32->offset : m_data_64->offset;
+}
+
+uint64_t lldb_private::formatters::NSArrayMSyntheticFrontEnd_1400::GetSize() {
+  if (!m_data_32 && !m_data_64)
+    return 0;
+  return m_data_32 ? m_data_32->size : m_data_64->size;
+}
+
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::NSArrayISyntheticFrontEnd_1300(
     lldb::ValueObjectSP valobj_sp)
     : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
       m_items(0), m_data_ptr(0) {
@@ -516,7 +676,7 @@
 }
 
 size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd::GetIndexOfChildWithName(
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetIndexOfChildWithName(
     const ConstString &name) {
   const char *item_name = name.GetCString();
   uint32_t idx = ExtractIndexFromString(item_name);
@@ -526,11 +686,11 @@
 }
 
 size_t
-lldb_private::formatters::NSArrayISyntheticFrontEnd::CalculateNumChildren() {
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::CalculateNumChildren() {
   return m_items;
 }
 
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd::Update() {
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::Update() {
   m_ptr_size = 0;
   m_items = 0;
   m_data_ptr = 0;
@@ -552,12 +712,12 @@
   return false;
 }
 
-bool lldb_private::formatters::NSArrayISyntheticFrontEnd::MightHaveChildren() {
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::MightHaveChildren() {
   return true;
 }
 
 lldb::ValueObjectSP
-lldb_private::formatters::NSArrayISyntheticFrontEnd::GetChildAtIndex(
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1300::GetChildAtIndex(
     size_t idx) {
   if (idx >= CalculateNumChildren())
     return lldb::ValueObjectSP();
@@ -575,6 +735,99 @@
                                       m_exe_ctx_ref, m_id_type);
 }
 
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::NSArrayISyntheticFrontEnd_1400(
+    lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+      m_data_32(nullptr), m_data_64(nullptr) {
+  if (valobj_sp) {
+    CompilerType type = valobj_sp->GetCompilerType();
+    if (type) {
+      ClangASTContext *ast = valobj_sp->GetExecutionContextRef()
+                                 .GetTargetSP()
+                                 ->GetScratchClangASTContext();
+      if (ast)
+        m_id_type = CompilerType(ast->getASTContext(),
+                                 ast->getASTContext()->ObjCBuiltinIdTy);
+    }
+  }
+}
+
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::~NSArrayISyntheticFrontEnd_1400() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+}
+
+size_t
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetIndexOfChildWithName(
+    const ConstString &name) {
+  const char *item_name = name.GetCString();
+  uint32_t idx = ExtractIndexFromString(item_name);
+  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+    return UINT32_MAX;
+  return idx;
+}
+
+size_t
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::CalculateNumChildren() {
+  return m_data_32 ? m_data_32->used : m_data_64->used;
+}
+
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::Update() {
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  m_ptr_size = 0;
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return false;
+  m_ptr_size = process_sp->GetAddressByteSize();
+  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+  if (m_ptr_size == 4) {
+    m_data_32 = new DataDescriptor_32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+                           error);
+  } else {
+    m_data_64 = new DataDescriptor_64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+                           error);
+  }
+  if (error.Fail())
+    return false;
+  return false;
+}
+
+bool lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::MightHaveChildren() {
+  return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSArrayISyntheticFrontEnd_1400::GetChildAtIndex(
+    size_t idx) {
+  if (idx >= CalculateNumChildren())
+    return lldb::ValueObjectSP();
+  lldb::addr_t object_at_idx = m_data_32 ? m_data_32->list : m_data_64->list;
+  object_at_idx += (idx * m_ptr_size);
+  ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+  if (!process_sp)
+    return lldb::ValueObjectSP();
+  Error error;
+  if (error.Fail())
+    return lldb::ValueObjectSP();
+  StreamString idx_name;
+  idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+  return CreateValueObjectFromAddress(idx_name.GetString(), object_at_idx,
+                                      m_exe_ctx_ref, m_id_type);
+}
+
 lldb_private::formatters::NSArray0SyntheticFrontEnd::NSArray0SyntheticFrontEnd(
     lldb::ValueObjectSP valobj_sp)
     : SyntheticChildrenFrontEnd(*valobj_sp) {}
@@ -683,17 +936,24 @@
   static const ConstString g_NSArrayM("__NSArrayM");
   static const ConstString g_NSArray0("__NSArray0");
   static const ConstString g_NSArray1("__NSSingleObjectArrayI");
+  static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy");
+  static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable");
 
   if (class_name.IsEmpty())
     return nullptr;
 
   if (class_name == g_NSArrayI) {
-    return (new NSArrayISyntheticFrontEnd(valobj_sp));
+      if (runtime->GetFoundationVersion() >= 1400)
+        return (new NSArrayISyntheticFrontEnd_1400(valobj_sp));
+      else
+        return (new NSArrayISyntheticFrontEnd_1300(valobj_sp));
   } else if (class_name == g_NSArray0) {
     return (new NSArray0SyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_NSArray1) {
     return (new NSArray1SyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_NSArrayM) {
+    if (runtime->GetFoundationVersion() >= 1400)
+      return (new NSArrayMSyntheticFrontEnd_1400(valobj_sp));
     if (runtime->GetFoundationVersion() >= 1100)
       return (new NSArrayMSyntheticFrontEnd_1010(valobj_sp));
     else
diff --git a/source/Plugins/Language/ObjC/NSDictionary.cpp b/source/Plugins/Language/ObjC/NSDictionary.cpp
index 23a445f..8cbb043 100644
--- a/source/Plugins/Language/ObjC/NSDictionary.cpp
+++ b/source/Plugins/Language/ObjC/NSDictionary.cpp
@@ -34,6 +34,7 @@
 
 // FIXME: we should not need this
 #include "Plugins/Language/Swift/SwiftDictionary.h"
+#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
 #include <mutex>
 
 using namespace lldb;
@@ -187,6 +188,52 @@
 
 private:
   struct DataDescriptor_32 {
+    uint32_t used : 26;
+    uint32_t kvo : 1;
+    uint32_t size;
+    uint32_t buffer;
+  };
+
+  struct DataDescriptor_64 {
+    uint64_t used : 58;
+    uint32_t kvo : 1;
+    uint64_t size;
+    uint64_t buffer;
+  };
+
+  struct DictionaryItemDescriptor {
+    lldb::addr_t key_ptr;
+    lldb::addr_t val_ptr;
+    lldb::ValueObjectSP valobj_sp;
+  };
+
+  ExecutionContextRef m_exe_ctx_ref;
+  uint8_t m_ptr_size;
+  lldb::ByteOrder m_order;
+  DataDescriptor_32 *m_data_32;
+  DataDescriptor_64 *m_data_64;
+  CompilerType m_pair_type;
+  std::vector<DictionaryItemDescriptor> m_children;
+};
+
+class NSDictionaryMLegacySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+public:
+  NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+
+  ~NSDictionaryMLegacySyntheticFrontEnd() override;
+
+  size_t CalculateNumChildren() override;
+
+  lldb::ValueObjectSP GetChildAtIndex(size_t idx) override;
+
+  bool Update() override;
+
+  bool MightHaveChildren() override;
+
+  size_t GetIndexOfChildWithName(const ConstString &name) override;
+
+private:
+  struct DataDescriptor_32 {
     uint32_t _used : 26;
     uint32_t _kvo : 1;
     uint32_t _size;
@@ -256,19 +303,21 @@
 
   static const ConstString g_DictionaryI("__NSDictionaryI");
   static const ConstString g_DictionaryM("__NSDictionaryM");
+  static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
+  static const ConstString g_DictionaryMImmutable("__NSDictionaryM_Immutable");
   static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
 
   if (class_name.IsEmpty())
     return false;
 
-  if (class_name == g_DictionaryI) {
+  if (class_name == g_DictionaryI || class_name == g_DictionaryMImmutable) {
     Error error;
     value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                       ptr_size, 0, error);
     if (error.Fail())
       return false;
     value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U);
-  } else if (class_name == g_DictionaryM) {
+  } else if (class_name == g_DictionaryM || class_name == g_DictionaryMLegacy) {
     Error error;
     value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size,
                                                       ptr_size, 0, error);
@@ -317,9 +366,8 @@
   lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
   if (!process_sp)
     return nullptr;
-  ObjCLanguageRuntime *runtime =
-      (ObjCLanguageRuntime *)process_sp->GetLanguageRuntime(
-          lldb::eLanguageTypeObjC);
+  AppleObjCRuntime *runtime =
+      llvm::dyn_cast_or_null<AppleObjCRuntime>(process_sp->GetObjCLanguageRuntime());
   if (!runtime)
     return nullptr;
 
@@ -344,6 +392,8 @@
   static const ConstString g_DictionaryI("__NSDictionaryI");
   static const ConstString g_DictionaryM("__NSDictionaryM");
   static const ConstString g_Dictionary1("__NSSingleEntryDictionaryI");
+  static const ConstString g_DictionaryImmutable("__NSDictionaryM_Immutable");
+  static const ConstString g_DictionaryMLegacy("__NSDictionaryM_Legacy");
 
   if (class_name.IsEmpty())
     return nullptr;
@@ -351,7 +401,13 @@
   if (class_name == g_DictionaryI) {
     return (new NSDictionaryISyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_DictionaryM) {
-    return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+    if (runtime->GetFoundationVersion() > 1400) {
+      return (new NSDictionaryMSyntheticFrontEnd(valobj_sp));
+    } else {
+      return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
+    }
+  } else if (class_name == g_DictionaryMLegacy) {
+      return (new NSDictionaryMLegacySyntheticFrontEnd(valobj_sp));
   } else if (class_name == g_Dictionary1) {
     return (new NSDictionary1SyntheticFrontEnd(valobj_sp));
   } else {
@@ -617,7 +673,7 @@
     CalculateNumChildren() {
   if (!m_data_32 && !m_data_64)
     return 0;
-  return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+  return (m_data_32 ? m_data_32->used : m_data_64->used);
 }
 
 bool lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::Update() {
@@ -661,6 +717,165 @@
 lldb::ValueObjectSP
 lldb_private::formatters::NSDictionaryMSyntheticFrontEnd::GetChildAtIndex(
     size_t idx) {
+  lldb::addr_t m_keys_ptr;
+  lldb::addr_t m_values_ptr;
+  if (m_data_32) {
+    uint32_t size = m_data_32->size;
+    m_keys_ptr = m_data_32->buffer;
+    m_values_ptr = m_data_32->buffer + (m_ptr_size * size);
+  } else {
+    uint32_t size = m_data_64->size;
+    m_keys_ptr = m_data_64->buffer;
+    m_values_ptr = m_data_64->buffer + (m_ptr_size * size);
+  }
+
+  uint32_t num_children = CalculateNumChildren();
+
+  if (idx >= num_children)
+    return lldb::ValueObjectSP();
+
+  if (m_children.empty()) {
+    // do the scan phase
+    lldb::addr_t key_at_idx = 0, val_at_idx = 0;
+
+    uint32_t tries = 0;
+    uint32_t test_idx = 0;
+
+    while (tries < num_children) {
+      key_at_idx = m_keys_ptr + (test_idx * m_ptr_size);
+      val_at_idx = m_values_ptr + (test_idx * m_ptr_size);
+      ;
+      ProcessSP process_sp = m_exe_ctx_ref.GetProcessSP();
+      if (!process_sp)
+        return lldb::ValueObjectSP();
+      Error error;
+      key_at_idx = process_sp->ReadPointerFromMemory(key_at_idx, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+      val_at_idx = process_sp->ReadPointerFromMemory(val_at_idx, error);
+      if (error.Fail())
+        return lldb::ValueObjectSP();
+
+      test_idx++;
+
+      if (!key_at_idx || !val_at_idx)
+        continue;
+      tries++;
+
+      DictionaryItemDescriptor descriptor = {key_at_idx, val_at_idx,
+                                             lldb::ValueObjectSP()};
+
+      m_children.push_back(descriptor);
+    }
+  }
+
+  if (idx >= m_children.size()) // should never happen
+    return lldb::ValueObjectSP();
+
+  DictionaryItemDescriptor &dict_item = m_children[idx];
+  if (!dict_item.valobj_sp) {
+    if (!m_pair_type.IsValid()) {
+      TargetSP target_sp(m_backend.GetTargetSP());
+      if (!target_sp)
+        return ValueObjectSP();
+      m_pair_type = GetLLDBNSPairType(target_sp);
+    }
+    if (!m_pair_type.IsValid())
+      return ValueObjectSP();
+
+    DataBufferSP buffer_sp(new DataBufferHeap(2 * m_ptr_size, 0));
+
+    if (m_ptr_size == 8) {
+      uint64_t *data_ptr = (uint64_t *)buffer_sp->GetBytes();
+      *data_ptr = dict_item.key_ptr;
+      *(data_ptr + 1) = dict_item.val_ptr;
+    } else {
+      uint32_t *data_ptr = (uint32_t *)buffer_sp->GetBytes();
+      *data_ptr = dict_item.key_ptr;
+      *(data_ptr + 1) = dict_item.val_ptr;
+    }
+
+    StreamString idx_name;
+    idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
+    DataExtractor data(buffer_sp, m_order, m_ptr_size);
+    dict_item.valobj_sp = CreateValueObjectFromData(idx_name.GetString(), data,
+                                                    m_exe_ctx_ref, m_pair_type);
+  }
+  return dict_item.valobj_sp;
+}
+
+
+lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
+    NSDictionaryMLegacySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
+    : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
+      m_order(lldb::eByteOrderInvalid), m_data_32(nullptr), m_data_64(nullptr),
+      m_pair_type() {}
+
+lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
+    ~NSDictionaryMLegacySyntheticFrontEnd() {
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+}
+
+size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
+    GetIndexOfChildWithName(const ConstString &name) {
+  const char *item_name = name.GetCString();
+  uint32_t idx = ExtractIndexFromString(item_name);
+  if (idx < UINT32_MAX && idx >= CalculateNumChildren())
+    return UINT32_MAX;
+  return idx;
+}
+
+size_t lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
+    CalculateNumChildren() {
+  if (!m_data_32 && !m_data_64)
+    return 0;
+  return (m_data_32 ? m_data_32->_used : m_data_64->_used);
+}
+
+bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::Update() {
+  m_children.clear();
+  ValueObjectSP valobj_sp = m_backend.GetSP();
+  m_ptr_size = 0;
+  delete m_data_32;
+  m_data_32 = nullptr;
+  delete m_data_64;
+  m_data_64 = nullptr;
+  if (!valobj_sp)
+    return false;
+  m_exe_ctx_ref = valobj_sp->GetExecutionContextRef();
+  Error error;
+  error.Clear();
+  lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
+  if (!process_sp)
+    return false;
+  m_ptr_size = process_sp->GetAddressByteSize();
+  m_order = process_sp->GetByteOrder();
+  uint64_t data_location = valobj_sp->GetValueAsUnsigned(0) + m_ptr_size;
+  if (m_ptr_size == 4) {
+    m_data_32 = new DataDescriptor_32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+                           error);
+  } else {
+    m_data_64 = new DataDescriptor_64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+                           error);
+  }
+  if (error.Fail())
+    return false;
+  return false;
+}
+
+bool lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::
+    MightHaveChildren() {
+  return true;
+}
+
+lldb::ValueObjectSP
+lldb_private::formatters::NSDictionaryMLegacySyntheticFrontEnd::GetChildAtIndex(
+    size_t idx) {
   lldb::addr_t m_keys_ptr =
       (m_data_32 ? m_data_32->_keys_addr : m_data_64->_keys_addr);
   lldb::addr_t m_values_ptr =
diff --git a/source/Plugins/Language/ObjC/NSSet.cpp b/source/Plugins/Language/ObjC/NSSet.cpp
index 542c242..60f56cc 100644
--- a/source/Plugins/Language/ObjC/NSSet.cpp
+++ b/source/Plugins/Language/ObjC/NSSet.cpp
@@ -13,6 +13,7 @@
 // Project includes
 #include "NSSet.h"
 
+#include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/Error.h"
 #include "lldb/Core/Stream.h"
@@ -84,11 +85,12 @@
   std::vector<SetItemDescriptor> m_children;
 };
 
-class NSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
+template <typename D32, typename D64>
+class GenericNSSetMSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
-  NSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
+  GenericNSSetMSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
 
-  ~NSSetMSyntheticFrontEnd() override;
+  ~GenericNSSetMSyntheticFrontEnd() override;
 
   size_t CalculateNumChildren() override;
 
@@ -101,19 +103,6 @@
   size_t GetIndexOfChildWithName(const ConstString &name) override;
 
 private:
-  struct DataDescriptor_32 {
-    uint32_t _used : 26;
-    uint32_t _size;
-    uint32_t _mutations;
-    uint32_t _objs_addr;
-  };
-
-  struct DataDescriptor_64 {
-    uint64_t _used : 58;
-    uint64_t _size;
-    uint64_t _mutations;
-    uint64_t _objs_addr;
-  };
 
   struct SetItemDescriptor {
     lldb::addr_t item_ptr;
@@ -122,11 +111,49 @@
 
   ExecutionContextRef m_exe_ctx_ref;
   uint8_t m_ptr_size;
-  DataDescriptor_32 *m_data_32;
-  DataDescriptor_64 *m_data_64;
+  D32 *m_data_32;
+  D64 *m_data_64;
   std::vector<SetItemDescriptor> m_children;
 };
-
+  
+namespace Foundation1300 {
+  struct DataDescriptor_32 {
+    uint32_t _used : 26;
+    uint32_t _size;
+    uint32_t _mutations;
+    uint32_t _objs_addr;
+  };
+  
+  struct DataDescriptor_64 {
+    uint64_t _used : 58;
+    uint64_t _size;
+    uint64_t _mutations;
+    uint64_t _objs_addr;
+  };
+  
+  using NSSetMSyntheticFrontEnd =
+      GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+  
+namespace Foundation1400 {
+  struct DataDescriptor_32 {
+    uint32_t _used : 26;
+    uint32_t _size;
+    uint32_t _objs_addr;
+    uint32_t _mutations;
+  };
+  
+  struct DataDescriptor_64 {
+    uint64_t _used : 58;
+    uint64_t _size;
+    uint64_t _objs_addr;
+    uint64_t _mutations;
+  };
+  
+  using NSSetMSyntheticFrontEnd =
+      GenericNSSetMSyntheticFrontEnd<DataDescriptor_32, DataDescriptor_64>;
+}
+  
 class NSSetCodeRunningSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
 public:
   NSSetCodeRunningSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp);
@@ -283,7 +310,12 @@
   if (!strcmp(class_name, "__NSSetI")) {
     return (new NSSetISyntheticFrontEnd(valobj_sp));
   } else if (!strcmp(class_name, "__NSSetM")) {
-    return (new NSSetMSyntheticFrontEnd(valobj_sp));
+    AppleObjCRuntime *apple_runtime =
+        llvm::dyn_cast_or_null<AppleObjCRuntime>(runtime);
+    if (apple_runtime && apple_runtime->GetFoundationVersion() >= 1400)
+      return (new Foundation1400::NSSetMSyntheticFrontEnd(valobj_sp));
+    else
+      return (new Foundation1300::NSSetMSyntheticFrontEnd(valobj_sp));
   } else {
     auto &map(NSSet_Additionals::GetAdditionalSynthetics());
     auto iter = map.find(class_name_cs), end = map.end();
@@ -442,7 +474,9 @@
   return set_item.valobj_sp;
 }
 
-lldb_private::formatters::NSSetMSyntheticFrontEnd::NSSetMSyntheticFrontEnd(
+template <typename D32, typename D64>
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::GenericNSSetMSyntheticFrontEnd(
     lldb::ValueObjectSP valobj_sp)
     : SyntheticChildrenFrontEnd(*valobj_sp), m_exe_ctx_ref(), m_ptr_size(8),
       m_data_32(nullptr), m_data_64(nullptr) {
@@ -450,15 +484,19 @@
     Update();
 }
 
-lldb_private::formatters::NSSetMSyntheticFrontEnd::~NSSetMSyntheticFrontEnd() {
+template <typename D32, typename D64>
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::~GenericNSSetMSyntheticFrontEnd() {
   delete m_data_32;
   m_data_32 = nullptr;
   delete m_data_64;
   m_data_64 = nullptr;
 }
 
+template <typename D32, typename D64>
 size_t
-lldb_private::formatters::NSSetMSyntheticFrontEnd::GetIndexOfChildWithName(
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::GetIndexOfChildWithName(
     const ConstString &name) {
   const char *item_name = name.GetCString();
   uint32_t idx = ExtractIndexFromString(item_name);
@@ -467,14 +505,19 @@
   return idx;
 }
 
+template <typename D32, typename D64>
 size_t
-lldb_private::formatters::NSSetMSyntheticFrontEnd::CalculateNumChildren() {
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::CalculateNumChildren() {
   if (!m_data_32 && !m_data_64)
     return 0;
   return (m_data_32 ? m_data_32->_used : m_data_64->_used);
 }
 
-bool lldb_private::formatters::NSSetMSyntheticFrontEnd::Update() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::Update() {
   m_children.clear();
   ValueObjectSP valobj_sp = m_backend.GetSP();
   m_ptr_size = 0;
@@ -500,12 +543,12 @@
   m_ptr_size = process_sp->GetAddressByteSize();
   uint64_t data_location = valobj_sp->GetAddressOf() + m_ptr_size;
   if (m_ptr_size == 4) {
-    m_data_32 = new DataDescriptor_32();
-    process_sp->ReadMemory(data_location, m_data_32, sizeof(DataDescriptor_32),
+    m_data_32 = new D32();
+    process_sp->ReadMemory(data_location, m_data_32, sizeof(D32),
                            error);
   } else {
-    m_data_64 = new DataDescriptor_64();
-    process_sp->ReadMemory(data_location, m_data_64, sizeof(DataDescriptor_64),
+    m_data_64 = new D64();
+    process_sp->ReadMemory(data_location, m_data_64, sizeof(D64),
                            error);
   }
   if (error.Fail())
@@ -513,12 +556,17 @@
   return false;
 }
 
-bool lldb_private::formatters::NSSetMSyntheticFrontEnd::MightHaveChildren() {
+template <typename D32, typename D64>
+bool
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::MightHaveChildren() {
   return true;
 }
 
+template <typename D32, typename D64>
 lldb::ValueObjectSP
-lldb_private::formatters::NSSetMSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
+lldb_private::formatters::
+  GenericNSSetMSyntheticFrontEnd<D32, D64>::GetChildAtIndex(size_t idx) {
   lldb::addr_t m_objs_addr =
       (m_data_32 ? m_data_32->_objs_addr : m_data_64->_objs_addr);
 
diff --git a/source/Plugins/Language/Swift/SwiftFormatters.cpp b/source/Plugins/Language/Swift/SwiftFormatters.cpp
index c4b2d02..4d3df75 100644
--- a/source/Plugins/Language/Swift/SwiftFormatters.cpp
+++ b/source/Plugins/Language/Swift/SwiftFormatters.cpp
@@ -376,7 +376,16 @@
   ValueObjectSP value_child(valobj.GetChildMemberWithName(g_value, true));
   if (!value_child)
     return false;
-  auto value = value_child->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+    
+  // Swift Bools are stored in a byte, but only the LSB of the byte is
+  // significant.  The swift::irgen::FixedTypeInfo structure represents
+  // this information by providing a mask of the "extra bits" for the type.
+  // But at present CompilerType has no way to represent that information.
+  // So for now we hard code it.
+  uint64_t value = value_child->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+  const uint64_t mask = 1 << 0;
+  value &= mask;
+  
   switch (value) {
   case 0:
     stream.Printf("false");
diff --git a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
index c5a3dde..97875c7 100644
--- a/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
+++ b/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp
@@ -47,7 +47,7 @@
 namespace {
 
 static PropertyDefinition g_properties[] = {
-    {"enable", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+    {"enable", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
      "Specify whether goroutines should be treated as threads."},
     {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}};
 
@@ -451,8 +451,14 @@
 OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err) {
   err.Clear();
   Goroutine result = {};
-  ValueObjectSP g =
-      m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err);
+  ValueObjectSP child_sp = m_allg_sp->GetSyntheticArrayMember(idx, true);
+  if (!child_sp) {
+    err.SetErrorToGenericError();
+    err.SetErrorString("unable to find goroutines in array");
+    return result;
+  }
+
+  ValueObjectSP g = child_sp->Dereference(err);
   if (err.Fail()) {
     return result;
   }
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index b08d1ad..9101f7d 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -4268,7 +4268,15 @@
             }
           }
         } else {
-          if (location_is_const_value_data)
+          // The heuristic for inferring static variables works for Clang's
+          // behavior on C-like languages, which generally does not emit
+          // AT_const_value for locals.
+          //
+          // However, the Swift compiler can and does emit AT_const_value for
+          // locals, and function-level statics don't exist, so we flip the
+          // heuristic here.
+          if (location_is_const_value_data &&
+              !IsSwiftLanguage(sc.comp_unit->GetLanguage()))
             scope = eValueTypeVariableStatic;
           else {
             scope = eValueTypeVariableLocal;
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 9aad2e1..fe31039 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -577,9 +577,10 @@
 }
 
 bool x86AssemblyInspectionEngine::instruction_length(uint8_t *insn_p,
-                                                     int &length) {
+                                                     int &length, 
+                                                     uint32_t buffer_remaining_bytes) {
 
-  const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
+  uint32_t max_op_byte_size = std::min(buffer_remaining_bytes, m_arch.GetMaximumOpcodeByteSize());
   llvm::SmallVector<uint8_t, 32> opcode_data;
   opcode_data.resize(max_op_byte_size);
 
@@ -671,8 +672,9 @@
     bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
 
     m_cur_insn = data + current_func_text_offset;
-    if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
-        insn_len > kMaxInstructionByteSize) {
+    if (!instruction_length(m_cur_insn, insn_len, size - current_func_text_offset)
+        || insn_len == 0 
+        || insn_len > kMaxInstructionByteSize) {
       // An unrecognized/junk instruction
       break;
     }
@@ -969,8 +971,9 @@
   while (offset < size) {
     m_cur_insn = data + offset;
     int insn_len;
-    if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
-        insn_len > kMaxInstructionByteSize) {
+    if (!instruction_length(m_cur_insn, insn_len, size - offset)
+        || insn_len == 0 
+        || insn_len > kMaxInstructionByteSize) {
       // An unrecognized/junk instruction.
       break;
     }
@@ -1181,8 +1184,9 @@
     int scratch;
 
     m_cur_insn = data + offset;
-    if (!instruction_length(m_cur_insn, insn_len) ||
-        insn_len > kMaxInstructionByteSize || insn_len == 0) {
+    if (!instruction_length(m_cur_insn, insn_len, size - offset) 
+        || insn_len > kMaxInstructionByteSize 
+        || insn_len == 0) {
       // An error parsing the instruction, i.e. probably data/garbage - stop
       // scanning
       break;
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index 0294f5a..abcaf8a 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -112,7 +112,7 @@
   bool ret_pattern_p();
   uint32_t extract_4(uint8_t *b);
 
-  bool instruction_length(uint8_t *insn, int &length);
+  bool instruction_length(uint8_t *insn, int &length, uint32_t buffer_remaining_bytes);
 
   bool machine_regno_to_lldb_regno(int machine_regno, uint32_t &lldb_regno);
 
diff --git a/source/Symbol/SwiftASTContext.cpp b/source/Symbol/SwiftASTContext.cpp
index 69b0cd8..dd7e9d0 100644
--- a/source/Symbol/SwiftASTContext.cpp
+++ b/source/Symbol/SwiftASTContext.cpp
@@ -4185,6 +4185,7 @@
     case swift::DeclKind::IfConfig:
     case swift::DeclKind::Param:
     case swift::DeclKind::Module:
+    case swift::DeclKind::MissingMember:
       break;
 
     case swift::DeclKind::InfixOperator:
diff --git a/source/Target/LanguageRuntime.cpp b/source/Target/LanguageRuntime.cpp
index bb3bba4..a3160e0 100644
--- a/source/Target/LanguageRuntime.cpp
+++ b/source/Target/LanguageRuntime.cpp
@@ -342,3 +342,25 @@
   else
     return eLanguageTypeUnknown;
 }
+
+bool
+LanguageRuntime::IsSymbolAnyRuntimeThunk(ProcessSP process_sp, Symbol &symbol)
+{
+  if (!process_sp)
+    return false;
+    
+  enum LanguageType languages_to_try[] = {
+      eLanguageTypeSwift, eLanguageTypeObjC, eLanguageTypeC_plus_plus};
+
+  LanguageRuntime *language_runtime;
+  for (enum LanguageType language : languages_to_try) {
+    language_runtime = process_sp->GetLanguageRuntime(language);
+    if (language_runtime) {
+        if (language_runtime->IsSymbolARuntimeThunk(symbol))
+          return true;
+    }
+  }
+  return false;
+}
+
+
diff --git a/source/Target/SwiftLanguageRuntime.cpp b/source/Target/SwiftLanguageRuntime.cpp
index 3adf2b2..d982526 100644
--- a/source/Target/SwiftLanguageRuntime.cpp
+++ b/source/Target/SwiftLanguageRuntime.cpp
@@ -366,6 +366,8 @@
   ValueObjectSP static_sp(object.GetStaticValue());
 
   CompilerType static_type(static_sp->GetCompilerType());
+  if (auto non_reference_type = static_type.GetNonReferenceType())
+    static_type = non_reference_type;
 
   Error error;
 
@@ -2781,13 +2783,12 @@
   if (num_global_children == 0)
     return ThunkKind::Unknown;
 
-  swift::Demangle::NodePointer global_node_ptr = nodes->getFirstChild();
-  if (global_node_ptr->getKind() != swift::Demangle::Node::Kind::Global)
+  if (nodes->getKind() != swift::Demangle::Node::Kind::Global)
     return ThunkKind::Unknown;
-  if (global_node_ptr->getNumChildren() == 0)
+  if (nodes->getNumChildren() == 0)
     return ThunkKind::Unknown;
 
-  swift::Demangle::NodePointer node_ptr = global_node_ptr->getFirstChild();
+  swift::Demangle::NodePointer node_ptr = nodes->getFirstChild();
   kind = node_ptr->getKind();
   switch (kind)
   {
@@ -2803,6 +2804,8 @@
     break;
   case swift::Demangle::Node::Kind::ReabstractionThunkHelper:
     return ThunkKind::Reabstraction;
+  case swift::Demangle::Node::Kind::PartialApplyForwarder:
+    return ThunkKind::PartialApply;
   case swift::Demangle::Node::Kind::Allocator:
     if (node_ptr->getNumChildren() == 0)
       return ThunkKind::Unknown;
@@ -2848,7 +2851,7 @@
       case ThunkKind::ObjCAttribute:
         return ThunkAction::GetThunkTarget;
       case ThunkKind::Reabstraction:
-        return ThunkAction::GetThunkTarget;
+        return ThunkAction::StepThrough;
       case ThunkKind::ProtocolConformance:
         return ThunkAction::StepIntoConformance;
     }
@@ -2900,7 +2903,9 @@
 bool SwiftLanguageRuntime::IsSymbolARuntimeThunk(const Symbol &symbol) {
 
   llvm::StringRef symbol_name = symbol.GetMangled().GetMangledName().GetStringRef();
-  
+  if (symbol_name.empty())
+    return false;
+
   swift::Demangle::Context demangle_ctx;
   return demangle_ctx.isThunkSymbol(symbol_name);
 }
diff --git a/source/Target/Thread.cpp b/source/Target/Thread.cpp
index 9a5e981..a4a1ce4 100644
--- a/source/Target/Thread.cpp
+++ b/source/Target/Thread.cpp
@@ -1391,6 +1391,28 @@
   return thread_plan_sp;
 }
 
+ThreadPlanSP Thread::QueueThreadPlanForStepInRangeNoShouldStop(
+    bool abort_other_plans, const AddressRange &range,
+    const SymbolContext &addr_context, const char *step_in_target,
+    lldb::RunMode stop_other_threads,
+    LazyBool step_in_avoids_code_without_debug_info,
+    LazyBool step_out_avoids_code_without_debug_info) {
+  ThreadPlanSP thread_plan_sp(
+      new ThreadPlanStepInRange(*this, range, addr_context, stop_other_threads,
+                                step_in_avoids_code_without_debug_info,
+                                step_out_avoids_code_without_debug_info));
+  ThreadPlanStepInRange *plan =
+      static_cast<ThreadPlanStepInRange *>(thread_plan_sp.get());
+
+  if (step_in_target)
+    plan->SetStepInTarget(step_in_target);
+    
+  plan->ClearShouldStopHereCallbacks();
+
+  QueueThreadPlan(thread_plan_sp, abort_other_plans);
+  return thread_plan_sp;
+}
+
 // Call the QueueThreadPlanForStepInRange method which takes an address range.
 ThreadPlanSP Thread::QueueThreadPlanForStepInRange(
     bool abort_other_plans, const LineEntry &line_entry,
diff --git a/source/Target/ThreadPlanShouldStopHere.cpp b/source/Target/ThreadPlanShouldStopHere.cpp
index cb16b3c..e0f2c35 100644
--- a/source/Target/ThreadPlanShouldStopHere.cpp
+++ b/source/Target/ThreadPlanShouldStopHere.cpp
@@ -90,20 +90,9 @@
   if (operation == eFrameCompareOlder) {
     Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
     if (symbol) {
-      LanguageRuntime *language_runtime;
-      bool is_thunk = false;
       ProcessSP process_sp(current_plan->GetThread().GetProcess());
-      enum LanguageType languages_to_try[] = {
-          eLanguageTypeSwift, eLanguageTypeObjC, eLanguageTypeC_plus_plus};
-
-      for (enum LanguageType language : languages_to_try) {
-        language_runtime = process_sp->GetLanguageRuntime(language);
-        if (language_runtime)
-          is_thunk = language_runtime->IsSymbolARuntimeThunk(*symbol);
-        if (is_thunk) {
+      if (LanguageRuntime::IsSymbolAnyRuntimeThunk(process_sp, *symbol)) {
           should_stop_here = false;
-          break;
-        }
       }
     }
   }
@@ -143,29 +132,54 @@
   if (sc.line_entry.line == 0) {
     AddressRange range = sc.line_entry.range;
 
-    // If the whole function is marked line 0 just step out, that's easier &
-    // faster than continuing
-    // to step through it.
+    // If this is a runtime thunk, just step out:
     bool just_step_out = false;
-    if (sc.symbol && sc.symbol->ValueIsAddress()) {
-      Address symbol_end = sc.symbol->GetAddress();
-      symbol_end.Slide(sc.symbol->GetByteSize() - 1);
-      if (range.ContainsFileAddress(sc.symbol->GetAddress()) &&
-          range.ContainsFileAddress(symbol_end)) {
-        if (log)
-          log->Printf("Stopped in a function with only line 0 lines, just "
-                      "stepping out.");
+    if (sc.symbol) {
+      ProcessSP process_sp(current_plan->GetThread().GetProcess());
+
+      if (LanguageRuntime::IsSymbolAnyRuntimeThunk(process_sp, *sc.symbol)) {
+          if (log)
+            log->Printf("In runtime thunk %s - stepping out.", 
+              sc.symbol->GetName().GetCString());
         just_step_out = true;
       }
+      // If the whole function is marked line 0 just step out, that's easier &
+      // faster than continuing to step through it.
+      // FIXME: This assumes that the function is a single line range.  It could
+      // be a series of contiguous line 0 ranges.  Check for that too.
+      if (!just_step_out && sc.symbol->ValueIsAddress()) {
+        Address symbol_end = sc.symbol->GetAddress();
+        symbol_end.Slide(sc.symbol->GetByteSize() - 1);
+        if (range.ContainsFileAddress(sc.symbol->GetAddress()) &&
+            range.ContainsFileAddress(symbol_end)) {
+          if (log)
+            log->Printf("Stopped in a function with only line 0 lines, just "
+                        "stepping out.");
+          just_step_out = true;
+        }
+      }
     }
+    
     if (!just_step_out) {
-      if (log)
-        log->Printf("ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
-                    "Queueing StepInRange plan to step through line 0 code.");
-
-      return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange(
-          false, range, sc, NULL, eOnlyDuringStepping, eLazyBoolCalculate,
-          eLazyBoolNo);
+      // If the current plan is a "Step In" plan we should use step in, otherwise
+      // just step over:
+      if (current_plan->GetKind() == ThreadPlan::eKindStepInRange) {
+        if (log)
+          log->Printf("ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
+                      "Queueing StepInRange plan to step through line 0 code.");
+        return_plan_sp = 
+          current_plan
+            ->GetThread().QueueThreadPlanForStepInRangeNoShouldStop(
+              false, range, sc, NULL, eOnlyDuringStepping, eLazyBoolCalculate,
+              eLazyBoolNo);
+      } else {
+        if (log)
+          log->Printf("ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
+                      "Queueing StepOverRange plan to step through line 0 code.");
+        return_plan_sp = 
+            current_plan->GetThread().QueueThreadPlanForStepOverRange(
+              false, range, sc, eOnlyDuringStepping, eLazyBoolNo);
+      }
     }
   }
 
diff --git a/source/Target/ThreadPlanStepOut.cpp b/source/Target/ThreadPlanStepOut.cpp
index 7a4bfb0..3118f77 100644
--- a/source/Target/ThreadPlanStepOut.cpp
+++ b/source/Target/ThreadPlanStepOut.cpp
@@ -372,6 +372,15 @@
     } else {
       m_step_out_further_plan_sp =
           QueueStepOutFromHerePlan(m_flags, eFrameCompareOlder);
+      if (m_step_out_further_plan_sp->GetKind() == eKindStepOut)
+      {
+        // If we are planning to step out further, then the frame we are going
+        // to step out to is about to go away, so we need to reset the frame
+        // we are stepping out to to the one our step out plan is aiming for.
+        ThreadPlanStepOut *as_step_out 
+          = static_cast<ThreadPlanStepOut *>(m_step_out_further_plan_sp.get());
+        m_step_out_to_id = as_step_out->m_step_out_to_id;
+      }
       done = false;
     }
   }
diff --git a/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp b/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
index e216d4b..49b6a5d 100644
--- a/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
+++ b/unittests/UnwindAssembly/x86/Testx86AssemblyInspectionEngine.cpp
@@ -2337,3 +2337,27 @@
 
   EXPECT_FALSE(row_sp->GetRegisterInfo(k_rbp, regloc));
 }
+
+// Give the disassembler random bytes to test that it doesn't exceed
+// the bounds of the array when run under clang's address sanitizer.
+TEST_F(Testx86AssemblyInspectionEngine, TestDisassemblyJunkBytes) {
+  AddressRange sample_range;
+  UnwindPlan unwind_plan(eRegisterKindLLDB);
+  std::unique_ptr<x86AssemblyInspectionEngine> engine32 = Geti386Inspector();
+  std::unique_ptr<x86AssemblyInspectionEngine> engine64 = Getx86_64Inspector();
+
+  uint8_t data[] = {
+      0x10, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+      0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
+
+  sample_range = AddressRange(0x1000, sizeof(data));
+
+  EXPECT_TRUE(engine32->GetNonCallSiteUnwindPlanFromAssembly(
+      data, sizeof(data), sample_range, unwind_plan));
+
+  unwind_plan.Clear();
+
+  EXPECT_TRUE(engine64->GetNonCallSiteUnwindPlanFromAssembly(
+      data, sizeof(data), sample_range, unwind_plan));
+
+}