Extend hack to work around bad exception specifications for 'swap' members to
also cover libstdc++'s std::__debug::array and std::__profile::array.

llvm-svn: 284669
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index a81ef51..74c5b42 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -43,23 +43,36 @@
   auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
 
   // All the problem cases are member functions named "swap" within class
-  // templates declared directly within namespace std.
-  if (!RD || !getStdNamespace() ||
-      !RD->getEnclosingNamespaceContext()->Equals(getStdNamespace()) ||
-      !RD->getIdentifier() || !RD->getDescribedClassTemplate() ||
+  // templates declared directly within namespace std or std::__debug or
+  // std::__profile.
+  if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() ||
       !D.getIdentifier() || !D.getIdentifier()->isStr("swap"))
     return false;
 
+  auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext());
+  if (!ND)
+    return false;
+
+  bool IsInStd = ND->isStdNamespace();
+  if (!IsInStd) {
+    // This isn't a direct member of namespace std, but it might still be
+    // libstdc++'s std::__debug::array or std::__profile::array.
+    IdentifierInfo *II = ND->getIdentifier();
+    if (!II || !(II->isStr("__debug") || II->isStr("__profile")) ||
+        !ND->isInStdNamespace())
+      return false;
+  }
+
   // Only apply this hack within a system header.
   if (!Context.getSourceManager().isInSystemHeader(D.getLocStart()))
     return false;
 
   return llvm::StringSwitch<bool>(RD->getIdentifier()->getName())
       .Case("array", true)
-      .Case("pair", true)
-      .Case("priority_queue", true)
-      .Case("stack", true)
-      .Case("queue", true)
+      .Case("pair", IsInStd)
+      .Case("priority_queue", IsInStd)
+      .Case("stack", IsInStd)
+      .Case("queue", IsInStd)
       .Default(false);
 }