Merge remote-tracking branch 'origin/swift-4.0-branch' into stable
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 2e41bc2..8c2cb30 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1767,6 +1767,7 @@
     if (TypeSourceInfo *TSI = D->getTypeAsWritten())                           \
       TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));                              \
                                                                                \
+    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));              \
     if (!getDerived().shouldVisitTemplateInstantiations() &&                   \
         D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)      \
       /* Returning from here skips traversing the                              \
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 72dc04e..4553b8d 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -3334,6 +3334,14 @@
     unsigned Idx = LeftToRight ? I : E - I - 1;
     CallExpr::const_arg_iterator Arg = ArgRange.begin() + Idx;
     if (!LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
+    // If *Arg is an ObjCIndirectCopyRestoreExpr, check that either the types of
+    // the argument and parameter match or the objc method is parameterized.
+    assert((!isa<ObjCIndirectCopyRestoreExpr>(*Arg) ||
+            getContext().hasSameUnqualifiedType((*Arg)->getType(),
+                                                ArgTypes[Idx]) ||
+            (isa<ObjCMethodDecl>(AC.getDecl()) &&
+             isObjCMethodWithTypeParams(cast<ObjCMethodDecl>(AC.getDecl())))) &&
+           "Argument and parameter types don't match");
     EmitCallArg(Args, *Arg, ArgTypes[Idx]);
     EmitNonNullArgCheck(Args.back().RV, ArgTypes[Idx], (*Arg)->getExprLoc(),
                         AC, ParamsToSkip + Idx);
@@ -3385,7 +3393,6 @@
   if (const ObjCIndirectCopyRestoreExpr *CRE
         = dyn_cast<ObjCIndirectCopyRestoreExpr>(E)) {
     assert(getLangOpts().ObjCAutoRefCount);
-    assert(getContext().hasSameUnqualifiedType(E->getType(), type));
     return emitWritebackArg(*this, args, CRE);
   }
 
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index d01e31f..68d134c 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -37,6 +37,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include <cstdlib> // ::getenv
 #include <system_error>
+#include <sys/utsname.h>
 
 using namespace clang::driver;
 using namespace clang::driver::toolchains;
@@ -510,6 +511,56 @@
   }
 }
 
+// Clang-900 specific change that's cherry-picked from the LLVM change r307372:
+static std::string getOSVersion() {
+  struct utsname info;
+
+  if (uname(&info))
+    return "";
+
+  return info.release;
+}
+
+static std::string updateTripleOSVersion(std::string TargetTripleString) {
+  // On darwin, we want to update the version to match that of the target.
+  std::string::size_type DarwinDashIdx = TargetTripleString.find("-darwin");
+  if (DarwinDashIdx != std::string::npos) {
+    TargetTripleString.resize(DarwinDashIdx + strlen("-darwin"));
+    TargetTripleString += getOSVersion();
+    return TargetTripleString;
+  }
+  std::string::size_type MacOSDashIdx = TargetTripleString.find("-macos");
+  if (MacOSDashIdx != std::string::npos) {
+    TargetTripleString.resize(MacOSDashIdx);
+    // Reset the OS to darwin as the OS version from `uname` doesn't use the
+    // macOS version scheme.
+    TargetTripleString += "-darwin";
+    TargetTripleString += getOSVersion();
+  }
+  return TargetTripleString;
+}
+
+/// Returns the most appropriate macOS target version for the current process.
+///
+/// If the macOS SDK version is the same or earlier than the system version,
+/// then the SDK version is returned. Otherwise the system version is returned.
+static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
+  unsigned Major, Minor, Micro;
+  llvm::Triple SystemTriple(updateTripleOSVersion(llvm::sys::getProcessTriple()));
+  if (!SystemTriple.isMacOSX())
+    return MacOSSDKVersion;
+  SystemTriple.getMacOSXVersion(Major, Minor, Micro);
+  VersionTuple SystemVersion(Major, Minor, Micro);
+  bool HadExtra;
+  if (!Driver::GetReleaseVersion(MacOSSDKVersion, Major, Minor, Micro,
+                                 HadExtra))
+    return MacOSSDKVersion;
+  VersionTuple SDKVersion(Major, Minor, Micro);
+  if (SDKVersion > SystemVersion)
+    return SystemVersion.getAsString();
+  return MacOSSDKVersion;
+}
+
 void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
   const OptTable &Opts = getDriver().getOpts();
 
@@ -602,7 +653,7 @@
                 SDK.startswith("iPhoneSimulator"))
               iOSTarget = Version;
             else if (SDK.startswith("MacOSX"))
-              OSXTarget = Version;
+              OSXTarget = getSystemOrSDKMacOSVersion(Version);
             else if (SDK.startswith("WatchOS") ||
                      SDK.startswith("WatchSimulator"))
               WatchOSTarget = Version;
diff --git a/lib/Frontend/SerializedDiagnosticReader.cpp b/lib/Frontend/SerializedDiagnosticReader.cpp
index c4461d4..81a483a 100644
--- a/lib/Frontend/SerializedDiagnosticReader.cpp
+++ b/lib/Frontend/SerializedDiagnosticReader.cpp
@@ -27,6 +27,9 @@
   llvm::BitstreamCursor Stream(**Buffer);
   Optional<llvm::BitstreamBlockInfo> BlockInfo;
 
+  if (Stream.AtEndOfStream())
+    return SDError::InvalidSignature;
+
   // Sniff for the signature.
   if (Stream.Read(8) != 'D' ||
       Stream.Read(8) != 'I' ||
diff --git a/test/CodeGenObjC/parameterized_classes.m b/test/CodeGenObjC/parameterized_classes.m
index 8fe5c52..34aca35 100644
--- a/test/CodeGenObjC/parameterized_classes.m
+++ b/test/CodeGenObjC/parameterized_classes.m
@@ -96,3 +96,31 @@
   _destination = a;
 }
 @end
+
+// CHECK-LABEL: define internal void @"\01-[C0 foo1]"(
+// CHECK: {{.*}} = alloca
+// CHECK: {{.*}} = alloca
+// CHECK: %[[D:.*]] = alloca %[[TY:.*]]*
+// CHECK: %[[TEMP:.*]] = alloca %[[TY]]*
+// CHECK: %[[V4:.*]] = load %[[TY]]*, %[[TY]]** %[[D]]
+// CHECK: store %[[TY]]* %[[V4]], %[[TY]]** %[[TEMP]]
+// CHECK: %[[V7:.*]] = bitcast %[[TY]]** %[[TEMP]] to i8**
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i8**)*)(i8* %{{.*}}, i8* %{{.*}}, i8** %[[V7]])
+
+@interface P0<ObjectType> : NSObject
+- (void)m0:(ObjectType *)first;
+@end
+
+@interface C0 : NSObject
+-(void)foo1;
+@end
+
+@implementation C0 {
+  P0<NSString *> *x;
+}
+
+-(void)foo1 {
+  NSString *d;
+  [x m0:&d];
+}
+@end
diff --git a/test/Driver/darwin-sdk-vs-os-version.c b/test/Driver/darwin-sdk-vs-os-version.c
new file mode 100644
index 0000000..391f4d5
--- /dev/null
+++ b/test/Driver/darwin-sdk-vs-os-version.c
@@ -0,0 +1,10 @@
+// REQUIRES: system-darwin
+
+// Ensure that we never pick a version that's based on the SDK that's newer than
+// the system version:
+// RUN: rm -rf %t/SDKs/MacOSX10.99.99.sdk
+// RUN: mkdir -p %t/SDKs/MacOSX10.99.99.sdk
+// RUN: %clang -target x86_64-apple-darwin -isysroot %t/SDKs/MacOSX10.99.99.sdk %s -### 2>&1 \
+// RUN:   | FileCheck --check-prefix=CHECK-MACOSX-SYSTEM-VERSION %s
+
+// CHECK-MACOSX-SYSTEM-VERSION-NOT: 10.99.99"
diff --git a/test/Index/Inputs/empty.dia b/test/Index/Inputs/empty.dia
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Index/Inputs/empty.dia
diff --git a/test/Index/read-empty-diags.test b/test/Index/read-empty-diags.test
new file mode 100644
index 0000000..cef751c
--- /dev/null
+++ b/test/Index/read-empty-diags.test
@@ -0,0 +1,2 @@
+// RUN: not c-index-test -read-diagnostics %S/Inputs/empty.dia 2>&1 | FileCheck %s
+// CHECK: Trouble deserializing file (Invalid File): Invalid diagnostics signature
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 269bdbb..887330c 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -158,4 +158,62 @@
                               "static int k = f();\n"));
 }
 
+// Check to ensure that nested name specifiers are visited.
+class NestedNameSpecifiersVisitor
+    : public ExpectedLocationVisitor<NestedNameSpecifiersVisitor> {
+public:
+  bool VisitRecordTypeLoc(RecordTypeLoc RTL) {
+    if (!RTL)
+      return true;
+    Match(RTL.getDecl()->getName(), RTL.getNameLoc());
+    return true;
+  }
+
+  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+    if (!NNS)
+      return true;
+    if (const NamespaceDecl *ND =
+            NNS.getNestedNameSpecifier()->getAsNamespace())
+      Match(ND->getName(), NNS.getLocalBeginLoc());
+    return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS);
+  }
+};
+
+TEST(RecursiveASTVisitor,
+     NestedNameSpecifiersForTemplateSpecializationsAreVisited) {
+  StringRef Source = R"(
+namespace ns {
+struct Outer {
+    template<typename T, typename U>
+    struct Nested { };
+
+    template<typename T>
+    static T x;
+};
+}
+
+template<>
+struct ns::Outer::Nested<int, int>;
+
+template<>
+struct ns::Outer::Nested<int, int> { };
+
+template<typename T>
+struct ns::Outer::Nested<int, T> { };
+
+template<>
+int ns::Outer::x<int> = 0;
+)";
+  NestedNameSpecifiersVisitor Visitor;
+  Visitor.ExpectMatch("ns", 13, 8);
+  Visitor.ExpectMatch("ns", 16, 8);
+  Visitor.ExpectMatch("ns", 19, 8);
+  Visitor.ExpectMatch("ns", 22, 5);
+  Visitor.ExpectMatch("Outer", 13, 12);
+  Visitor.ExpectMatch("Outer", 16, 12);
+  Visitor.ExpectMatch("Outer", 19, 12);
+  Visitor.ExpectMatch("Outer", 22, 9);
+  EXPECT_TRUE(Visitor.runOver(Source, NestedNameSpecifiersVisitor::Lang_CXX14));
+}
+
 } // end anonymous namespace