Refine the SlangRS::compile() API.

This makes compile() methods in SlangRS more reasonable. And this is
part of commits for ODR. The SlangRS::compile() now compiles "a group of
RS files" instead of one by one individually.
diff --git a/Android.mk b/Android.mk
index 4986a45..05066e5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -191,6 +191,7 @@
 	DeclNodes.inc    \
 	DiagnosticCommonKinds.inc   \
 	DiagnosticDriverKinds.inc	\
+	DiagnosticFrontendKinds.inc	\
 	DiagnosticSemaKinds.inc	\
 	StmtNodes.inc	\
 	RSCCOptions.inc
diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp
index f10e548..afd99b4 100644
--- a/llvm-rs-cc.cpp
+++ b/llvm-rs-cc.cpp
@@ -314,75 +314,6 @@
   return SaveStringInSet(SavedStrings, OutputFile);
 }
 
-static bool GenerateBitcodeAccessor(const char *InputFile,
-                                    const char *OutputFile,
-                                    const char *PackageName,
-                                    const RSCCOptions &Opts) {
-  if ((Opts.mOutputType != Slang::OT_Bitcode) ||
-      (Opts.mBitcodeStorage != BCST_JAVA_CODE))
-    return true;
-
-  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
-  BCAccessorContext.rsFileName = InputFile;
-  BCAccessorContext.bcFileName = OutputFile;
-  BCAccessorContext.reflectPath = Opts.mJavaReflectionPathBase.c_str();
-  BCAccessorContext.packageName = PackageName;
-  BCAccessorContext.bcStorage = Opts.mBitcodeStorage;
-
-  return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext);
-}
-
-// ExecuteCompilation -
-static bool ExecuteCompilation(SlangRS &Compiler,
-                               const char *InputFile,
-                               const char *OutputFile,
-                               const char *BCOutputFile,
-                               const char *DepOutputFile,
-                               const RSCCOptions &Opts) {
-  std::string RealPackageName;
-
-  Compiler.reset();
-
-  Compiler.setIncludePaths(Opts.mIncludePaths);
-  Compiler.setOutputType(Opts.mOutputType);
-  Compiler.allowRSPrefix(Opts.mAllowRSPrefix);
-
-  if (!Compiler.setInputSource(InputFile))
-    return false;
-
-  if (!Compiler.setOutput(OutputFile))
-    return false;
-
-  if (Opts.mOutputDep) {
-    if (!Compiler.setDepOutput(DepOutputFile))
-      return false;
-
-    Compiler.setDepTargetBC(BCOutputFile);
-    Compiler.setAdditionalDepTargets(Opts.mAdditionalDepTargets);
-
-    if (Compiler.generateDepFile() > 0)
-      return false;
-  }
-
-  if (Compiler.compile() > 0)
-    return false;
-
-  if (Opts.mOutputType != Slang::OT_Dependency) {
-    if (!Compiler.reflectToJava(Opts.mJavaReflectionPathBase,
-                                Opts.mJavaReflectionPackageName,
-                                &RealPackageName))
-      return false;
-
-    if (!GenerateBitcodeAccessor(InputFile,
-                                 OutputFile,
-                                 RealPackageName.c_str(),
-                                 Opts))
-      return false;
-  }
-
-  return true;
-}
-
 int main(int argc, const char **argv) {
   std::set<std::string> SavedStrings;
   llvm::SmallVector<const char*, 256> ArgVector;
@@ -430,37 +361,53 @@
     return 1;
   }
 
-  const char *InputFile, *OutputFile, *BCOutputFile = NULL,
-             *DepOutputFile = NULL;
+  // Prepare input data for RS compiler.
+  std::list<std::pair<const char*, const char*> > IOFiles;
+  std::list<std::pair<const char*, const char*> > DepFiles;
+
   llvm::OwningPtr<SlangRS> Compiler(new SlangRS(Opts.mTriple, Opts.mCPU,
                                                 Opts.mFeatures));
 
   for (int i = 0, e = Inputs.size(); i != e; i++) {
-    InputFile = Inputs[i];
-    OutputFile = DetermineOutputFile(Opts.mOutputDir, InputFile,
-                                     Opts.mOutputType, SavedStrings);
+    const char *InputFile = Inputs[i];
+    const char *OutputFile =
+        DetermineOutputFile(Opts.mOutputDir, InputFile,
+                            Opts.mOutputType, SavedStrings);
+
     if (Opts.mOutputDep) {
-      if (Opts.mOutputType == Slang::OT_Dependency)
-        DepOutputFile = OutputFile;
-      else
-        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
-                                            Slang::OT_Dependency, SavedStrings);
+      const char *BCOutputFile, *DepOutputFile;
 
       if (Opts.mOutputType == Slang::OT_Bitcode)
         BCOutputFile = OutputFile;
       else
         BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
                                            Slang::OT_Bitcode, SavedStrings);
+
+      if (Opts.mOutputType == Slang::OT_Dependency)
+        DepOutputFile = OutputFile;
+      else
+        DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
+                                            Slang::OT_Dependency, SavedStrings);
+
+      DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
     }
-    if (!ExecuteCompilation(*Compiler,
-                            InputFile,
-                            OutputFile,
-                            BCOutputFile,
-                            DepOutputFile,
-                            Opts)) {
-      llvm::errs() << Compiler->getErrorMessage();
-      return 1;
-    }
+
+    IOFiles.push_back(std::make_pair(InputFile, OutputFile));
+  }
+
+  // Let's rock!
+  if (!Compiler->compile(IOFiles,
+                         DepFiles,
+                         Opts.mIncludePaths,
+                         Opts.mAdditionalDepTargets,
+                         Opts.mOutputType,
+                         Opts.mBitcodeStorage,
+                         Opts.mAllowRSPrefix,
+                         Opts.mOutputDep,
+                         Opts.mJavaReflectionPathBase,
+                         Opts.mJavaReflectionPackageName)) {
+    llvm::errs() << Compiler->getErrorMessage();
+    return 1;
   }
 
   return 0;
diff --git a/slang_rs.cpp b/slang_rs.cpp
index 98ce3b8..b71e904 100644
--- a/slang_rs.cpp
+++ b/slang_rs.cpp
@@ -18,6 +18,8 @@
 
 #include <cstring>
 
+#include "clang/Frontend/FrontendDiagnostic.h"
+
 #include "clang/Sema/SemaDiagnostic.h"
 
 #include "slang_rs_backend.h"
@@ -39,12 +41,37 @@
 ENUM_RS_HEADER()
 #undef RS_HEADER_ENTRY
 
+bool SlangRS::reflectToJava(const std::string &OutputPathBase,
+                            const std::string &OutputPackageName,
+                            std::string *RealPackageName) {
+  return mRSContext->reflectToJava(OutputPathBase,
+                                   OutputPackageName,
+                                   getInputFileName(),
+                                   getOutputFileName(),
+                                   RealPackageName);
+}
+
+bool SlangRS::generateBitcodeAccessor(const std::string &OutputPathBase,
+                                      const std::string &PackageName) {
+  RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
+
+  BCAccessorContext.rsFileName = getInputFileName().c_str();
+  BCAccessorContext.bcFileName = getOutputFileName().c_str();
+  BCAccessorContext.reflectPath = OutputPathBase.c_str();
+  BCAccessorContext.packageName = PackageName.c_str();
+  BCAccessorContext.bcStorage = BCST_JAVA_CODE;   // Must be BCST_JAVA_CODE
+
+  return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext);
+}
+
+
 void SlangRS::initDiagnostic() {
   clang::Diagnostic &Diag = getDiagnostics();
-  if (!Diag.setDiagnosticGroupMapping(
-        "implicit-function-declaration", clang::diag::MAP_ERROR))
-    assert(false && "Unable to find option group "
-        "implicit-function-declaration");
+  if (Diag.setDiagnosticGroupMapping("implicit-function-declaration",
+                                     clang::diag::MAP_ERROR))
+    Diag.Report(clang::diag::warn_unknown_warning_option)
+        << "implicit-function-declaration";
+
   Diag.setDiagnosticMapping(
       clang::diag::ext_typecheck_convert_discards_qualifiers,
       clang::diag::MAP_ERROR);
@@ -107,24 +134,84 @@
   return;
 }
 
-bool SlangRS::reflectToJava(const std::string &OutputPathBase,
-                            const std::string &OutputPackageName,
-                            std::string *RealPackageName) {
-  if (mRSContext)
-    return mRSContext->reflectToJava(OutputPathBase,
-                                     OutputPackageName,
-                                     getInputFileName(),
-                                     getOutputFileName(),
-                                     RealPackageName);
-  else
-    return false;
-}
+bool SlangRS::compile(
+    const std::list<std::pair<const char*, const char*> > &IOFiles,
+    const std::list<std::pair<const char*, const char*> > &DepFiles,
+    const std::vector<std::string> &IncludePaths,
+    const std::vector<std::string> &AdditionalDepTargets,
+    Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage,
+    bool AllowRSPrefix, bool OutputDep,
+    const std::string &JavaReflectionPathBase,
+    const std::string &JavaReflectionPackageName) {
+  if (IOFiles.empty())
+    return true;
 
-void SlangRS::reset() {
-  Slang::reset();
-  delete mRSContext;
-  mRSContext = NULL;
-  return;
+  if (OutputDep && (DepFiles.size() != IOFiles.size())) {
+    fprintf(stderr, "SlangRS::compile() : Invalid parameter for output "
+                    "dependencies files.\n");
+    return false;
+  }
+
+  std::string RealPackageName;
+
+  const char *InputFile, *OutputFile, *BCOutputFile, *DepOutputFile;
+  std::list<std::pair<const char*, const char*> >::const_iterator
+      IOFileIter = IOFiles.begin(), DepFileIter = DepFiles.begin();
+
+  setIncludePaths(IncludePaths);
+  setOutputType(OutputType);
+  if (OutputDep)
+    setAdditionalDepTargets(AdditionalDepTargets);
+
+  mAllowRSPrefix = AllowRSPrefix;
+
+  for (unsigned i = 0, e = IOFiles.size(); i != e; i++) {
+    InputFile = IOFileIter->first;
+    OutputFile = IOFileIter->second;
+
+    reset();
+
+    if (!setInputSource(InputFile))
+      return false;
+
+    if (!setOutput(OutputFile))
+      return false;
+
+    if (OutputDep) {
+      BCOutputFile = DepFileIter->first;
+      DepOutputFile = DepFileIter->second;
+
+      setDepTargetBC(BCOutputFile);
+
+      if (!setDepOutput(DepOutputFile))
+        return false;
+
+      if (generateDepFile() > 0)
+        return false;
+
+      DepFileIter++;
+    }
+
+    if (Slang::compile() > 0)
+      return false;
+
+    if (OutputType != Slang::OT_Dependency) {
+      if (!reflectToJava(JavaReflectionPathBase,
+                         JavaReflectionPackageName,
+                         &RealPackageName))
+        return false;
+
+      if ((OutputType == Slang::OT_Bitcode) &&
+          (BitcodeStorage == BCST_JAVA_CODE) &&
+          !generateBitcodeAccessor(JavaReflectionPathBase,
+                                     RealPackageName.c_str()))
+          return false;
+    }
+
+    IOFileIter++;
+  }
+
+  return true;
 }
 
 SlangRS::~SlangRS() {
diff --git a/slang_rs.h b/slang_rs.h
index a8da424..6769744 100644
--- a/slang_rs.h
+++ b/slang_rs.h
@@ -19,6 +19,12 @@
 
 #include "slang.h"
 
+#include <list>
+#include <vector>
+#include <string>
+
+#include "slang_rs_reflect_utils.h"
+
 namespace slang {
   class RSContext;
 
@@ -29,6 +35,14 @@
 
   bool mAllowRSPrefix;
 
+  // The package name that's really applied will be filled in RealPackageName.
+  bool reflectToJava(const std::string &OutputPathBase,
+                     const std::string &OutputPackageName,
+                     std::string *RealPackageName);
+
+  bool generateBitcodeAccessor(const std::string &OutputPathBase,
+                               const std::string &PackageName);
+
  protected:
   virtual void initDiagnostic();
   virtual void initPreprocessor();
@@ -46,14 +60,41 @@
   SlangRS(const std::string &Triple, const std::string &CPU,
           const std::vector<std::string> &Features);
 
-  // The package name that's really applied will be filled in RealPackageName.
-  bool reflectToJava(const std::string &OutputPathBase,
-                     const std::string &OutputPackageName,
-                     std::string *RealPackageName);
-
-  virtual void reset();
-
-  inline void allowRSPrefix(bool V = true) { mAllowRSPrefix = V; }
+  // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if
+  // all given input files are successfully compiled without errors.
+  //
+  // @IOFiles - List of pairs of <input file path, output file path>.
+  //
+  // @DepFiles - List of pairs of <output dep. file path, dependent bitcode
+  //             target>. If @OutputDep is true, this parameter must be given
+  //             with the same number of pairs given in @IOFiles.
+  //
+  // @IncludePaths - User-defined include path.
+  //
+  // @AdditionalDepTargets - User-defined files added to the dependencies.
+  //
+  // @OutputType - See Slang::OutputType.
+  //
+  // @BitcodeStorage - See BitCodeStorageType in slang_rs_reflect_util.cpp.
+  //
+  // @AllowRSPrefix - true to allow user-defined function prefixed with 'rs'.
+  //
+  // @OutputDep - true if output dependecies file.
+  //
+  // @JavaReflectionPathBase - The path base for storing reflection files.
+  //
+  // @JavaReflectionPackageName - The package name given by user in command
+  //                              line. This may override the package name
+  //                              specified in the .rs using #pragma.
+  //
+  bool compile(const std::list<std::pair<const char*, const char*> > &IOFiles,
+               const std::list<std::pair<const char*, const char*> > &DepFiles,
+               const std::vector<std::string> &IncludePaths,
+               const std::vector<std::string> &AdditionalDepTargets,
+               Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage,
+               bool AllowRSPrefix, bool OutputDep,
+               const std::string &JavaReflectionPathBase,
+               const std::string &JavaReflectionPackageName);
 
   virtual ~SlangRS();
 };