[PCH] Really, pinky swear, fix for PR12689

rdar://11353109

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156145 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index a9d0fc3..11e237e 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -597,6 +597,8 @@
   /// switch statement can refer to them.
   std::map<unsigned, SwitchCase *> SwitchCaseStmts;
 
+  std::map<unsigned, SwitchCase *> *CurrSwitchCaseStmts;
+
   /// \brief The number of stat() calls that hit/missed the stat
   /// cache.
   unsigned NumStatHits, NumStatMisses;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index f1ea091..736d934 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6248,18 +6248,19 @@
 /// \brief Record that the given ID maps to the given switch-case
 /// statement.
 void ASTReader::RecordSwitchCaseID(SwitchCase *SC, unsigned ID) {
-  assert(SwitchCaseStmts[ID] == 0 && "Already have a SwitchCase with this ID");
-  SwitchCaseStmts[ID] = SC;
+  assert((*CurrSwitchCaseStmts)[ID] == 0 &&
+         "Already have a SwitchCase with this ID");
+  (*CurrSwitchCaseStmts)[ID] = SC;
 }
 
 /// \brief Retrieve the switch-case statement with the given ID.
 SwitchCase *ASTReader::getSwitchCaseWithID(unsigned ID) {
-  assert(SwitchCaseStmts[ID] != 0 && "No SwitchCase with this ID");
-  return SwitchCaseStmts[ID];
+  assert((*CurrSwitchCaseStmts)[ID] != 0 && "No SwitchCase with this ID");
+  return (*CurrSwitchCaseStmts)[ID];
 }
 
 void ASTReader::ClearSwitchCaseIDs() {
-  SwitchCaseStmts.clear();
+  CurrSwitchCaseStmts->clear();
 }
 
 void ASTReader::finishPendingActions() {
@@ -6374,7 +6375,8 @@
     DisableValidation(DisableValidation),
     DisableStatCache(DisableStatCache),
     AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), 
-    CurrentGeneration(0), NumStatHits(0), NumStatMisses(0), 
+    CurrentGeneration(0), CurrSwitchCaseStmts(&SwitchCaseStmts),
+    NumStatHits(0), NumStatMisses(0), 
     NumSLocEntriesRead(0), TotalNumSLocEntries(0), 
     NumStatementsRead(0), TotalNumStatements(0), NumMacrosRead(0), 
     TotalNumMacros(0), NumSelectorsRead(0), NumMethodPoolEntriesRead(0), 
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 15aa90b..dc315f0 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -25,6 +25,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "llvm/Support/SaveAndRestore.h"
 using namespace clang;
 using namespace clang::serialization;
 
@@ -629,8 +630,10 @@
   if (Record[Idx++]) {
     // In practice, this won't be executed (since method definitions
     // don't occur in header files).
-    // Switch case IDs are per method body.
-    Reader.ClearSwitchCaseIDs();
+    // Switch case IDs for this method body.
+    std::map<unsigned, SwitchCase *> SwitchCaseStmtsForObjCMethod;
+    SaveAndRestore<std::map<unsigned, SwitchCase *> *>
+      SCFOM(Reader.CurrSwitchCaseStmts, &SwitchCaseStmtsForObjCMethod);
     MD->setBody(Reader.ReadStmt(F));
     MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
     MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx));
diff --git a/test/PCH/objc_methods.h b/test/PCH/objc_methods.h
index 7b9e22d..6dfa248 100644
--- a/test/PCH/objc_methods.h
+++ b/test/PCH/objc_methods.h
@@ -25,3 +25,17 @@
   }
 }
 @end
+
+@interface PR12689_2
+@end
+
+@implementation PR12689_2
+-(void)mugi:(int)x {
+    switch(x) {
+        case 23: [self bonk:x]; break;
+        case 82: break;
+    }
+}
+-(void)bonk:(int)x {
+}
+@end