Fix an assertion triggered when using anonymous structs in kernel
signatures.

With asserts enabled, using an anonymous structure in the signature of
a kernel would cause an assertion to be triggered, which caused slang
to exit prematurely instead of printing an error diagnostic.

The problem is in the code in RSExportForEach::Create that exports
the types in the kernel signature. I changed this code not to throw
asserts when it sees a type that cannot be exported. However, since we
expect an error in this circumstance, I added an assert to ensure
that the diagnostic has been issued.

Change-Id: I727695b07d1310c8317b973499faa8088e2b0b4e
diff --git a/slang_rs_export_foreach.cpp b/slang_rs_export_foreach.cpp
index 7035a43..dff2112 100644
--- a/slang_rs_export_foreach.cpp
+++ b/slang_rs_export_foreach.cpp
@@ -517,27 +517,40 @@
     }
   }
 
-  if (FE->hasIns()) {
+  // Construct type information about inputs and outputs. Return null when
+  // there is an error exporting types.
 
+  bool TypeExportError = false;
+
+  if (FE->hasIns()) {
     for (InIter BI = FE->mIns.begin(), EI = FE->mIns.end(); BI != EI; BI++) {
       const clang::Type *T = (*BI)->getType().getCanonicalType().getTypePtr();
       RSExportType *InExportType = RSExportType::Create(Context, T);
 
-      if (FE->mIsKernelStyle) {
-        slangAssert(InExportType != nullptr);
+      if (!InExportType) {
+        TypeExportError = true;
       }
 
       FE->mInTypes.push_back(InExportType);
     }
   }
 
+  const clang::Type *OutType = nullptr;
   if (FE->mIsKernelStyle && FE->mHasReturnType) {
-    const clang::Type *T = FE->mResultType.getTypePtr();
-    FE->mOutType = RSExportType::Create(Context, T);
-    slangAssert(FE->mOutType);
+    OutType = FE->mResultType.getTypePtr();
   } else if (FE->mOut) {
-    const clang::Type *T = FE->mOut->getType().getCanonicalType().getTypePtr();
-    FE->mOutType = RSExportType::Create(Context, T);
+    OutType = FE->mOut->getType().getCanonicalType().getTypePtr();
+  }
+
+  if (OutType) {
+    FE->mOutType = RSExportType::Create(Context, OutType);
+    TypeExportError |= !FE->mOutType;
+  }
+
+  if (TypeExportError) {
+     slangAssert(Context->getDiagnostics()->hasErrorOccurred() &&
+                 "Error exporting type but no diagnostic message issued!");
+     return nullptr;
   }
 
   return FE;
diff --git a/tests/F_anon_struct_kernel_sig/anon_struct_kernel_sig.rs b/tests/F_anon_struct_kernel_sig/anon_struct_kernel_sig.rs
new file mode 100644
index 0000000..028a328
--- /dev/null
+++ b/tests/F_anon_struct_kernel_sig/anon_struct_kernel_sig.rs
@@ -0,0 +1,21 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+typedef struct {
+  int i;
+} myStruct;
+
+/* Test old-style kernel */
+void root(const myStruct *in, int *out) {
+  *out = in->i;
+}
+
+/* Test new-style kernel */
+myStruct RS_KERNEL kernel_returning_myStruct(int in) {
+  myStruct out = { in };
+  return out;
+}
+
+int RS_KERNEL kernel_with_myStruct_param(myStruct in) {
+  return in.i;
+}
diff --git a/tests/F_anon_struct_kernel_sig/stderr.txt.expect b/tests/F_anon_struct_kernel_sig/stderr.txt.expect
new file mode 100644
index 0000000..276aaaf
--- /dev/null
+++ b/tests/F_anon_struct_kernel_sig/stderr.txt.expect
@@ -0,0 +1 @@
+anon_struct_kernel_sig.rs:4:9: error: anonymous structures cannot be exported
diff --git a/tests/F_anon_struct_kernel_sig/stdout.txt.expect b/tests/F_anon_struct_kernel_sig/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_anon_struct_kernel_sig/stdout.txt.expect