[arcmt] Make sure the objc migrators work fine when used with a PCH.

rdar://13140508

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174386 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index af223a1..6282284 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -18,6 +18,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Rewrite/Core/Rewriter.h"
 #include "clang/Sema/SemaDiagnostic.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/MemoryBuffer.h"
 using namespace clang;
@@ -174,8 +175,24 @@
 createInvocationForMigration(CompilerInvocation &origCI) {
   OwningPtr<CompilerInvocation> CInvok;
   CInvok.reset(new CompilerInvocation(origCI));
-  CInvok->getPreprocessorOpts().ImplicitPCHInclude = std::string();
-  CInvok->getPreprocessorOpts().ImplicitPTHInclude = std::string();
+  PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
+  if (!PPOpts.ImplicitPCHInclude.empty()) {
+    // We can't use a PCH because it was likely built in non-ARC mode and we
+    // want to parse in ARC. Include the original header.
+    FileManager FileMgr(origCI.getFileSystemOpts());
+    IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+        new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(),
+                              new IgnoringDiagConsumer()));
+    std::string OriginalFile =
+        ASTReader::getOriginalSourceFile(PPOpts.ImplicitPCHInclude,
+                                         FileMgr, *Diags);
+    if (!OriginalFile.empty())
+      PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile);
+    PPOpts.ImplicitPCHInclude.clear();
+  }
+  // FIXME: Get the original header of a PTH as well.
+  CInvok->getPreprocessorOpts().ImplicitPTHInclude.clear();
   std::string define = getARCMTMacroName();
   define += '=';
   CInvok->getPreprocessorOpts().addMacroDef(define);
diff --git a/test/ARCMT/check-with-pch.m b/test/ARCMT/check-with-pch.m
new file mode 100644
index 0000000..7867002
--- /dev/null
+++ b/test/ARCMT/check-with-pch.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin10 %S/Common.h -emit-pch -o %t.pch
+// RUN: %clang_cc1 -include-pch %t.pch -arcmt-check -verify -triple x86_64-apple-darwin10 -fblocks -Werror %s
+// DISABLE: mingw32
+
+// rdar://9601437
+@interface I9601437 {
+  __unsafe_unretained id x;
+}
+-(void)Meth;
+@end
+
+@implementation I9601437
+-(void)Meth {
+  self->x = [NSObject new]; // expected-error {{assigning retained object}}
+}
+@end
diff --git a/test/ARCMT/migrate-with-pch.m b/test/ARCMT/migrate-with-pch.m
new file mode 100644
index 0000000..7dca8be
--- /dev/null
+++ b/test/ARCMT/migrate-with-pch.m
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c %S/Common.h -emit-pch -o %t.pch
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c -include-pch %t.pch 
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c -include-pch %t.pch
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result
+// RUN: rm -rf %t
+// DISABLE: mingw32
diff --git a/test/ARCMT/objcmt-with-pch.m b/test/ARCMT/objcmt-with-pch.m
new file mode 100644
index 0000000..fac42c8
--- /dev/null
+++ b/test/ARCMT/objcmt-with-pch.m
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %S/Common.h -emit-pch -o %t.pch
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -include-pch %t.pch
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result -include-pch %t.pch
+
+@interface NSNumber : NSObject
+@end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+void foo() {
+  NSNumber *n = [NSNumber numberWithInt:1];
+}
diff --git a/test/ARCMT/objcmt-with-pch.m.result b/test/ARCMT/objcmt-with-pch.m.result
new file mode 100644
index 0000000..04eadc9
--- /dev/null
+++ b/test/ARCMT/objcmt-with-pch.m.result
@@ -0,0 +1,16 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -x objective-c %S/Common.h -emit-pch -o %t.pch
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -include-pch %t.pch
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c %s.result -include-pch %t.pch
+
+@interface NSNumber : NSObject
+@end
+
+@interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithInt:(int)value;
+@end
+
+void foo() {
+  NSNumber *n = @1;
+}