Bug fix: support self-referential struct type.
diff --git a/slang_rs_export_type.cpp b/slang_rs_export_type.cpp
index 1028eb6..6542c5d 100644
--- a/slang_rs_export_type.cpp
+++ b/slang_rs_export_type.cpp
@@ -86,7 +86,6 @@
           return cname;                                       \
         break;
 #include "RSClangBuiltinEnums.inc"
-#undef ENUM_SUPPORT_BUILTIN_TYPE
         default: {
           assert(false && "Unknown data type of the builtin");
           break;
@@ -165,7 +164,6 @@
 #define ENUM_SUPPORT_BUILTIN_TYPE(builtin_type, type, cname)  \
         case builtin_type:
 #include "RSClangBuiltinEnums.inc"
-#undef ENUM_SUPPORT_BUILTIN_TYPE
           return T;
         default: {
           return NULL;
@@ -403,11 +401,12 @@
   return;
 }
 
-void RSExportType::keep() {
+bool RSExportType::keep() {
+  if (!RSExportable::keep())
+    return false;
   // Invalidate converted LLVM type.
   mLLVMType = NULL;
-  RSExportable::keep();
-  return;
+  return true;
 }
 
 bool RSExportType::equals(const RSExportable *E) const {
@@ -437,7 +436,6 @@
 #define ENUM_RS_OBJECT_TYPE(type, cname)                            \
     RSObjectTypeMap->GetOrCreateValue(cname, DataType ## type);
 #include "RSObjectTypeEnums.inc"
-#undef ENUM_RS_OBJECT_TYPE
   }
 
   RSObjectTypeMapTy::const_iterator I = RSObjectTypeMap->find(TypeName);
@@ -460,7 +458,6 @@
 #define ENUM_RS_DATA_TYPE(type, cname, bits)  \
   bits,
 #include "RSDataTypeEnums.inc"
-#undef ENUM_RS_DATA_TYPE
   0   // DataTypeMax
 };
 
@@ -485,7 +482,6 @@
           return DataType ## type;                            \
         }
 #include "RSClangBuiltinEnums.inc"
-#undef ENUM_SUPPORT_BUILTIN_TYPE
         // The size of type WChar depend on platform so we abandon the support
         // to them.
         default: {
@@ -637,9 +633,11 @@
   return llvm::PointerType::getUnqual(PointeeType);
 }
 
-void RSExportPointerType::keep() {
+bool RSExportPointerType::keep() {
+  if (!RSExportType::keep())
+    return false;
   const_cast<RSExportType*>(mPointeeType)->keep();
-  RSExportType::keep();
+  return true;
 }
 
 bool RSExportPointerType::equals(const RSExportable *E) const {
@@ -672,7 +670,6 @@
       break;                                                  \
     }
 #include "RSClangBuiltinEnums.inc"
-#undef ENUM_SUPPORT_BUILTIN_TYPE
     default: {
       return llvm::StringRef();
     }
@@ -819,10 +816,11 @@
   return llvm::ArrayType::get(mElementType->getLLVMType(), getSize());
 }
 
-void RSExportConstantArrayType::keep() {
+bool RSExportConstantArrayType::keep() {
+  if (!RSExportType::keep())
+    return false;
   const_cast<RSExportType*>(mElementType)->keep();
-  RSExportType::keep();
-  return;
+  return true;
 }
 
 bool RSExportConstantArrayType::equals(const RSExportable *E) const {
@@ -903,10 +901,14 @@
 }
 
 const llvm::Type *RSExportRecordType::convertToLLVMType() const {
+  // Create an opaque type since struct may reference itself recursively.
+  llvm::PATypeHolder ResultHolder =
+      llvm::OpaqueType::get(getRSContext()->getLLVMContext());
+  setAbstractLLVMType(ResultHolder.get());
+
   std::vector<const llvm::Type*> FieldTypes;
 
-  for (const_field_iterator FI = fields_begin(),
-           FE = fields_end();
+  for (const_field_iterator FI = fields_begin(), FE = fields_end();
        FI != FE;
        FI++) {
     const Field *F = *FI;
@@ -915,20 +917,27 @@
     FieldTypes.push_back(FET->getLLVMType());
   }
 
-  return llvm::StructType::get(getRSContext()->getLLVMContext(),
-                               FieldTypes,
-                               mIsPacked);
+  llvm::StructType *ST = llvm::StructType::get(getRSContext()->getLLVMContext(),
+                                               FieldTypes,
+                                               mIsPacked);
+  if (ST != NULL)
+    static_cast<llvm::OpaqueType*>(ResultHolder.get())
+        ->refineAbstractTypeTo(ST);
+  else
+    return NULL;
+  return ResultHolder.get();
 }
 
-void RSExportRecordType::keep() {
+bool RSExportRecordType::keep() {
+  if (!RSExportType::keep())
+    return false;
   for (std::list<const Field*>::iterator I = mFields.begin(),
           E = mFields.end();
        I != E;
        I++) {
     const_cast<RSExportType*>((*I)->getType())->keep();
   }
-  RSExportType::keep();
-  return;
+  return true;
 }
 
 bool RSExportRecordType::equals(const RSExportable *E) const {