[ExternalASTMerger] Import Objective-C classes

This patch adds functionality and a test for importing Objective-C classes
and their methods.

It also adds a flag to clang-import-test to set the language used for
parsing. This takes the same argument format as the -x option to the
driver.

Differential Revision: https://reviews.llvm.org/D35274

llvm-svn: 309014
diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp
index 6b724e9..286cb05 100644
--- a/clang/tools/clang-import-test/clang-import-test.cpp
+++ b/clang/tools/clang-import-test/clang-import-test.cpp
@@ -17,6 +17,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/CodeGen/ModuleBuilder.h"
+#include "clang/Driver/Types.h"
 #include "clang/Frontend/ASTConsumers.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/MultiplexConsumer.h"
@@ -53,6 +54,11 @@
               llvm::cl::desc("Argument to pass to the CompilerInvocation"),
               llvm::cl::CommaSeparated);
 
+static llvm::cl::opt<std::string>
+    Input("x", llvm::cl::Optional,
+          llvm::cl::desc("The language to parse (default: c++)"),
+          llvm::cl::init("c++"));
+
 static llvm::cl::opt<bool>
 DumpAST("dump-ast", llvm::cl::init(false),
         llvm::cl::desc("Dump combined AST"));
@@ -110,6 +116,7 @@
     llvm::errs() << LineString << '\n';
     llvm::errs().indent(LocColumn);
     llvm::errs() << '^';
+    llvm::errs() << '\n';
   }
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
@@ -143,7 +150,7 @@
 };
 
 std::unique_ptr<CompilerInstance>
-BuildCompilerInstance(ArrayRef<const char *> ClangArgv) {
+BuildCompilerInstance() {
   auto Ins = llvm::make_unique<CompilerInstance>();
   auto DC = llvm::make_unique<TestDiagnosticConsumer>();
   const bool ShouldOwnClient = true;
@@ -151,13 +158,27 @@
 
   auto Inv = llvm::make_unique<CompilerInvocation>();
 
+  std::vector<const char *> ClangArgv(ClangArgs.size());
+  std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
+                 [](const std::string &s) -> const char * { return s.data(); });
   CompilerInvocation::CreateFromArgs(*Inv, ClangArgv.data(),
                                      &ClangArgv.data()[ClangArgv.size()],
                                      Ins->getDiagnostics());
 
-  Inv->getLangOpts()->CPlusPlus = true;
-  Inv->getLangOpts()->CPlusPlus11 = true;
-  Inv->getHeaderSearchOpts().UseLibcxx = true;
+  {
+    using namespace driver::types;
+    ID Id = lookupTypeForTypeSpecifier(Input.c_str());
+    assert(Id != TY_INVALID);
+    if (isCXX(Id)) {
+      Inv->getLangOpts()->CPlusPlus = true;
+      Inv->getLangOpts()->CPlusPlus11 = true;
+      Inv->getHeaderSearchOpts().UseLibcxx = true;
+    }
+    if (isObjC(Id)) {
+      Inv->getLangOpts()->ObjC1 = 1;
+      Inv->getLangOpts()->ObjC2 = 1;
+    }
+  }
   Inv->getLangOpts()->Bool = true;
   Inv->getLangOpts()->WChar = true;
   Inv->getLangOpts()->Blocks = true;
@@ -216,11 +237,8 @@
 }
 
 std::unique_ptr<CompilerInstance> BuildIndirect(std::unique_ptr<CompilerInstance> &CI) {
-  std::vector<const char *> ClangArgv(ClangArgs.size());
-  std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
-                 [](const std::string &s) -> const char * { return s.data(); });
   std::unique_ptr<CompilerInstance> IndirectCI =
-      init_convenience::BuildCompilerInstance(ClangArgv);
+      init_convenience::BuildCompilerInstance();
   auto ST = llvm::make_unique<SelectorTable>();
   auto BC = llvm::make_unique<Builtin::Context>();
   std::unique_ptr<ASTContext> AST =
@@ -247,11 +265,8 @@
 Parse(const std::string &Path,
       llvm::ArrayRef<std::unique_ptr<CompilerInstance>> Imports,
       bool ShouldDumpAST) {
-  std::vector<const char *> ClangArgv(ClangArgs.size());
-  std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
-                 [](const std::string &s) -> const char * { return s.data(); });
   std::unique_ptr<CompilerInstance> CI =
-      init_convenience::BuildCompilerInstance(ClangArgv);
+      init_convenience::BuildCompilerInstance();
   auto ST = llvm::make_unique<SelectorTable>();
   auto BC = llvm::make_unique<Builtin::Context>();
   std::unique_ptr<ASTContext> AST =