Improve validation of AST before reflection.

Change-Id: If4b52f3a713ab97145bc31ef42b18d1cc144099a
diff --git a/slang_rs_backend.cpp b/slang_rs_backend.cpp
index c2d8305..332b28e 100644
--- a/slang_rs_backend.cpp
+++ b/slang_rs_backend.cpp
@@ -104,8 +104,52 @@
   return;
 }
 
-void RSBackend::HandleTranslationUnitPre(clang::ASTContext& C) {
+namespace {
+
+bool ValidateVar(clang::VarDecl *VD) {
+  llvm::StringRef TypeName;
+  const clang::Type *T = VD->getType().getTypePtr();
+  if (!RSExportType::NormalizeType(T, TypeName)) {
+    return false;
+  }
+  return true;
+}
+
+bool ValidateASTContext(clang::ASTContext &C, clang::Diagnostic &Diags) {
+  bool valid = true;
   clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
+  for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
+          DE = TUDecl->decls_end();
+       DI != DE;
+       DI++) {
+    if (DI->getKind() == clang::Decl::Var) {
+      clang::VarDecl *VD = (clang::VarDecl*) (*DI);
+      if (VD->getLinkage() == clang::ExternalLinkage) {
+        if (!ValidateVar(VD)) {
+          valid = false;
+          VD = VD->getCanonicalDecl();
+          Diags.Report(clang::FullSourceLoc(VD->getLocation(),
+                                            C.getSourceManager()),
+                       Diags.getCustomDiagID(clang::Diagnostic::Error,
+                                             "variable cannot be "
+                                             "exported: '%0'"))
+              << VD->getName();
+        }
+      }
+    }
+  }
+
+  return valid;
+}
+
+}  // end namespace
+
+void RSBackend::HandleTranslationUnitPre(clang::ASTContext &C) {
+  clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
+
+  if (!ValidateASTContext(C, mDiags)) {
+    return;
+  }
 
   // Process any static function declarations
   for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
@@ -124,6 +168,7 @@
   if (!mContext->processExport()) {
     mDiags.Report(mDiags.getCustomDiagID(clang::Diagnostic::Error,
                                          "elements cannot be exported"));
+    return;
   }
 
   // Dump export variable info
diff --git a/slang_rs_backend.h b/slang_rs_backend.h
index 976283b..c7a3582 100644
--- a/slang_rs_backend.h
+++ b/slang_rs_backend.h
@@ -60,7 +60,7 @@
  protected:
   virtual void HandleTopLevelDecl(clang::DeclGroupRef D);
 
-  virtual void HandleTranslationUnitPre(clang::ASTContext& C);
+  virtual void HandleTranslationUnitPre(clang::ASTContext &C);
 
   virtual void HandleTranslationUnitPost(llvm::Module *M);
 
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index f537985..86e8607 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -174,7 +174,7 @@
   clang::TranslationUnitDecl *TUDecl = mCtx.getTranslationUnitDecl();
   for (clang::DeclContext::decl_iterator DI = TUDecl->decls_begin(),
            DE = TUDecl->decls_end();
-       DI != TUDecl->decls_end();
+       DI != DE;
        DI++) {
     if (DI->getKind() == clang::Decl::Var) {
       clang::VarDecl *VD = (clang::VarDecl*) (*DI);
diff --git a/tests/F_ptr_in_struct/ptr_in_struct.rs b/tests/F_ptr_in_struct/ptr_in_struct.rs
index 76d9d89..db580db 100644
--- a/tests/F_ptr_in_struct/ptr_in_struct.rs
+++ b/tests/F_ptr_in_struct/ptr_in_struct.rs
@@ -1,7 +1,7 @@
 #pragma version(1)
 #pragma rs java_package_name(foo)
 
-typedef struct s {
+struct s {
     int *i;
 };
 
diff --git a/tests/F_ptr_in_struct/stderr.txt.expect b/tests/F_ptr_in_struct/stderr.txt.expect
index 670e721..637f1e5 100644
--- a/tests/F_ptr_in_struct/stderr.txt.expect
+++ b/tests/F_ptr_in_struct/stderr.txt.expect
@@ -1,5 +1,3 @@
 Field `i' in Record `s' contains unsupported type
 : int *identifier
-RSContext::processExport : failed to export var 'myStruct'
-ptr_in_struct.rs:4:1: warning: declaration does not declare anything
-error: elements cannot be exported
+ptr_in_struct.rs:8:10: error: variable cannot be exported: 'myStruct'