am a6031c8a: Merge "Don\'t allow user-defined uninitialized const variables to be exported."

* commit 'a6031c8a30c269b02f5549f9e427ed0242b7493b':
  Don't allow user-defined uninitialized const variables to be exported.
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index 6b07804..bc674a0 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -77,8 +77,6 @@
 bool RSContext::processExportVar(const clang::VarDecl *VD) {
   slangAssert(!VD->getName().empty() && "Variable name should not be empty");
 
-  // TODO(zonr): some check on variable
-
   RSExportType *ET = RSExportType::CreateFromDecl(this, VD);
   if (!ET)
     return false;
@@ -231,8 +229,25 @@
     switch (D->getKind()) {
     case clang::Decl::Var: {
       clang::VarDecl* VD = llvm::dyn_cast<clang::VarDecl>(D);
+      bool ShouldExportVariable = true;
       if (VD->getFormalLinkage() == clang::ExternalLinkage) {
-        if (!processExportVar(VD)) {
+        clang::QualType QT = VD->getTypeSourceInfo()->getType();
+        if (QT.isConstQualified() && !VD->hasInit()) {
+          if (Slang::IsLocInRSHeaderFile(VD->getLocation(),
+                                         *getSourceManager())) {
+            // We don't export variables internal to the runtime's
+            // implementation.
+            ShouldExportVariable = false;
+          } else {
+            clang::DiagnosticsEngine *DiagEngine = getDiagnostics();
+            DiagEngine->Report(VD->getLocation(), DiagEngine->getCustomDiagID(
+                clang::DiagnosticsEngine::Error,
+                "invalid declaration of uninitialized constant variable '%0'"))
+              << VD->getName();
+            valid = false;
+          }
+        }
+        if (valid && ShouldExportVariable && !processExportVar(VD)) {
           valid = false;
         }
       }
diff --git a/tests/F_extern_const/extern_const.rs b/tests/F_extern_const/extern_const.rs
new file mode 100644
index 0000000..bf630de
--- /dev/null
+++ b/tests/F_extern_const/extern_const.rs
@@ -0,0 +1,4 @@
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+extern const int extern_const_int;
diff --git a/tests/F_extern_const/stderr.txt.expect b/tests/F_extern_const/stderr.txt.expect
new file mode 100644
index 0000000..567c9a5
--- /dev/null
+++ b/tests/F_extern_const/stderr.txt.expect
@@ -0,0 +1 @@
+extern_const.rs:4:18: error: invalid declaration of uninitialized constant variable 'extern_const_int'
diff --git a/tests/F_extern_const/stdout.txt.expect b/tests/F_extern_const/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_extern_const/stdout.txt.expect
diff --git a/tests/P_constant/constant.rs b/tests/P_constant/constant.rs
index 6f98ff1..4457e37 100644
--- a/tests/P_constant/constant.rs
+++ b/tests/P_constant/constant.rs
@@ -18,3 +18,5 @@
 
 const bool boolTest = true;
 
+extern const int i = 5;
+
diff --git a/tests/P_constant/stderr.txt.expect b/tests/P_constant/stderr.txt.expect
index e69de29..3728bee 100644
--- a/tests/P_constant/stderr.txt.expect
+++ b/tests/P_constant/stderr.txt.expect
@@ -0,0 +1 @@
+constant.rs:21:18: warning: 'extern' variable has an initializer
diff --git a/tests/P_extern_const/extern_const.rs b/tests/P_extern_const/extern_const.rs
new file mode 100644
index 0000000..e80906a
--- /dev/null
+++ b/tests/P_extern_const/extern_const.rs
@@ -0,0 +1,7 @@
+// -I .
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int __attribute__((kernel)) foo() {
+    return my_extern_const_in_header;
+}
diff --git a/tests/P_extern_const/rs_core.rsh b/tests/P_extern_const/rs_core.rsh
new file mode 100644
index 0000000..4332ed0
--- /dev/null
+++ b/tests/P_extern_const/rs_core.rsh
@@ -0,0 +1,8 @@
+// Fake rs_core.rsh header file
+//
+// We use -I . to pick up this header file implicitly, instead of the proper
+// rs_core.rsh header file.
+
+// Declare an uninitialized external constant, which should be ok for our
+// official header files.
+extern const int my_extern_const_in_header;
diff --git a/tests/P_extern_const/stderr.txt.expect b/tests/P_extern_const/stderr.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_extern_const/stderr.txt.expect
diff --git a/tests/P_extern_const/stdout.txt.expect b/tests/P_extern_const/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_extern_const/stdout.txt.expect