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'