Implement one-definition-rule (ODR) feature.

When compiling multiple RS files, we say two RS files A and B break ODR
iff:

1. They have at least one common struct named [S] and [S] will be reflected
to ScriptField_[S].java, and
2. [S] defined in A is not *exactly the same* (number of fields, field
type and field name) as the one defined in B.

This CL detects such error.
diff --git a/slang_rs.h b/slang_rs.h
index 6769744..613de76 100644
--- a/slang_rs.h
+++ b/slang_rs.h
@@ -23,10 +23,13 @@
 #include <vector>
 #include <string>
 
+#include "llvm/ADT/StringMap.h"
+
 #include "slang_rs_reflect_utils.h"
 
 namespace slang {
   class RSContext;
+  class RSExportRecordType;
 
 class SlangRS : public Slang {
  private:
@@ -35,6 +38,20 @@
 
   bool mAllowRSPrefix;
 
+  // Custom diagnostic identifiers
+  unsigned mDiagErrorInvalidOutputDepParameter;
+  unsigned mDiagErrorODR;
+
+  // FIXME: Should be std::list<RSExportable *> here. But currently we only
+  //        check ODR on record type.
+  //
+  // ReflectedDefinitions maps record type name to a pair:
+  //  <its RSExportRecordType instance,
+  //   the first file contains this record type definition>
+  typedef std::pair<RSExportRecordType*, const char*> ReflectedDefinitionTy;
+  typedef llvm::StringMap<ReflectedDefinitionTy> ReflectedDefinitionListTy;
+  ReflectedDefinitionListTy ReflectedDefinitions;
+
   // The package name that's really applied will be filled in RealPackageName.
   bool reflectToJava(const std::string &OutputPathBase,
                      const std::string &OutputPackageName,
@@ -43,6 +60,8 @@
   bool generateBitcodeAccessor(const std::string &OutputPathBase,
                                const std::string &PackageName);
 
+  bool checkODR();
+
  protected:
   virtual void initDiagnostic();
   virtual void initPreprocessor();
@@ -57,8 +76,7 @@
  public:
   static bool IsRSHeaderFile(const char *File);
 
-  SlangRS(const std::string &Triple, const std::string &CPU,
-          const std::vector<std::string> &Features);
+  SlangRS();
 
   // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if
   // all given input files are successfully compiled without errors.
@@ -69,7 +87,7 @@
   //             target>. If @OutputDep is true, this parameter must be given
   //             with the same number of pairs given in @IOFiles.
   //
-  // @IncludePaths - User-defined include path.
+  // @IncludePaths - User-defined include paths.
   //
   // @AdditionalDepTargets - User-defined files added to the dependencies.
   //
@@ -79,7 +97,7 @@
   //
   // @AllowRSPrefix - true to allow user-defined function prefixed with 'rs'.
   //
-  // @OutputDep - true if output dependecies file.
+  // @OutputDep - true if output dependecies file for each input file.
   //
   // @JavaReflectionPathBase - The path base for storing reflection files.
   //
@@ -96,6 +114,8 @@
                const std::string &JavaReflectionPathBase,
                const std::string &JavaReflectionPackageName);
 
+  virtual void reset();
+
   virtual ~SlangRS();
 };
 }