Change the name for the new rs_context parameter.

Change the reserved name for the new rs_context parameter to be "context".

Since there can be only one rs_context parameter, report an  error if the
name is incorrect.

Also use "special parameter" consistently in the error messages to help
our developers distinguish between regular and special parameters.

Finally, some refactoring to make the code more understandable.

b/21647353

Change-Id: I6f23dc5a8ba3659714ad1f7ba41836ff8b92d9ec
diff --git a/slang_rs_export_foreach.cpp b/slang_rs_export_foreach.cpp
index d622c01..d539e13 100644
--- a/slang_rs_export_foreach.cpp
+++ b/slang_rs_export_foreach.cpp
@@ -37,8 +37,8 @@
 const size_t RS_KERNEL_INPUT_LIMIT = 8; // see frameworks/base/libs/rs/cpu_ref/rsCpuCoreRuntime.h
 
 enum SpecialParameterKind {
-  SPK_INT,  // 'int' or 'unsigned int'
-  SPK_CTXT, // rs_kernel_context
+  SPK_LOCATION, // 'int' or 'unsigned int'
+  SPK_CONTEXT,  // rs_kernel_context
 };
 
 struct SpecialParameter {
@@ -50,20 +50,23 @@
 
 // Table entries are in the order parameters must occur in a kernel parameter list.
 const SpecialParameter specialParameterTable[] = {
-  { "ctxt", bcinfo::MD_SIG_Ctxt, SPK_CTXT, SLANG_M_TARGET_API },
-  { "x", bcinfo::MD_SIG_X, SPK_INT, SLANG_MINIMUM_TARGET_API },
-  { "y", bcinfo::MD_SIG_Y, SPK_INT, SLANG_MINIMUM_TARGET_API },
-  { "z", bcinfo::MD_SIG_Z, SPK_INT, SLANG_M_TARGET_API },
-  { nullptr, bcinfo::MD_SIG_None, SPK_INT, SLANG_MINIMUM_TARGET_API }, // marks end of table
+  { "context", bcinfo::MD_SIG_Ctxt, SPK_CONTEXT, SLANG_M_TARGET_API },
+  { "x", bcinfo::MD_SIG_X, SPK_LOCATION, SLANG_MINIMUM_TARGET_API },
+  { "y", bcinfo::MD_SIG_Y, SPK_LOCATION, SLANG_MINIMUM_TARGET_API },
+  { "z", bcinfo::MD_SIG_Z, SPK_LOCATION, SLANG_M_TARGET_API },
+  { nullptr, bcinfo::MD_SIG_None, SPK_LOCATION, SLANG_MINIMUM_TARGET_API }, // marks end of table
 };
 
 // If the specified name matches the name of an entry in
-// specialParameterTable, return the corresponding table index;
-// otherwise return -1.
+// specialParameterTable, return the corresponding table index.
+// Return -1 if not found.
 int lookupSpecialParameter(const llvm::StringRef name) {
-  for (int i = 0; specialParameterTable[i].name != nullptr; ++i)
-    if (name.equals(specialParameterTable[i].name))
+  for (int i = 0; specialParameterTable[i].name != nullptr; ++i) {
+    if (name.equals(specialParameterTable[i].name)) {
       return i;
+    }
+  }
+
   return -1;
 }
 
@@ -145,7 +148,7 @@
   // Validate remaining parameter types
 
   size_t IndexOfFirstSpecialParameter = numParams;
-  valid |= validateSpecialParameters(Context, FD, &IndexOfFirstSpecialParameter);
+  valid |= processSpecialParameters(Context, FD, &IndexOfFirstSpecialParameter);
 
   // Validate the non-special parameters, which should all be found before the
   // first special parameter.
@@ -156,7 +159,7 @@
     if (!QT->isPointerType()) {
       Context->ReportError(PVD->getLocation(),
                            "Compute kernel %0() cannot have non-pointer "
-                           "parameters besides (%1). Parameter '%2' is "
+                           "parameters besides special parameters (%1). Parameter '%2' is "
                            "of type: '%3'")
           << FD->getName() << listSpecialParameters(Context->getTargetAPI())
           << PVD->getName() << PVD->getType().getAsString();
@@ -233,7 +236,7 @@
   // Validate remaining parameter types
 
   size_t IndexOfFirstSpecialParameter = numParams;
-  valid |= validateSpecialParameters(Context, FD, &IndexOfFirstSpecialParameter);
+  valid |= processSpecialParameters(Context, FD, &IndexOfFirstSpecialParameter);
 
   // Validate the non-special parameters, which should all be found before the
   // first special.
@@ -286,10 +289,12 @@
   return valid;
 }
 
-// Search for the optional special parameters.  Returns true if valid.   Also
-// sets *IndexOfFirstSpecialParameter to the index of the first special parameter, or
-// FD->getNumParams() if none are found.
-bool RSExportForEach::validateSpecialParameters(
+// Process the optional special parameters:
+// - Sets *IndexOfFirstSpecialParameter to the index of the first special parameter, or
+//     FD->getNumParams() if none are found.
+// - Sets mSpecialParameterSignatureMetadata for the found special parameters.
+// Returns true if no errors.
+bool RSExportForEach::processSpecialParameters(
     RSContext *Context, const clang::FunctionDecl *FD,
     size_t *IndexOfFirstSpecialParameter) {
   slangAssert(IndexOfFirstSpecialParameter != nullptr);
@@ -298,104 +303,119 @@
 
   // Find all special parameters if present.
   int LastSpecialParameterIdx = -1;     // index into specialParameterTable
-  int FirstIntSpecialParameterIdx = -1; // index into specialParameterTable
-  clang::QualType FirstIntSpecialParameterType;
+  int FirstLocationSpecialParameterIdx = -1; // index into specialParameterTable
+  clang::QualType FirstLocationSpecialParameterType;
   size_t NumParams = FD->getNumParams();
   *IndexOfFirstSpecialParameter = NumParams;
   bool valid = true;
   for (size_t i = 0; i < NumParams; i++) {
     const clang::ParmVarDecl *PVD = FD->getParamDecl(i);
-    llvm::StringRef ParamName = PVD->getName();
+    const llvm::StringRef ParamName = PVD->getName();
+    const clang::QualType Type = PVD->getType();
+    const clang::QualType QT = Type.getCanonicalType();
+    const clang::QualType UT = QT.getUnqualifiedType();
     int SpecialParameterIdx = lookupSpecialParameter(ParamName);
-    if (SpecialParameterIdx >= 0) {
-      const SpecialParameter &SP = specialParameterTable[SpecialParameterIdx];
-      // We won't be invoked if two parameters of the same name are present.
-      slangAssert(!(mSpecialParameterSignatureMetadata & SP.bitval));
 
-      if (Context->getTargetAPI() < SP.minAPI) {
-        Context->ReportError(PVD->getLocation(),
-                             "Compute kernel %0() targeting SDK levels "
-                             "%1-%2 may not use parameter '%3'.")
-            << FD->getName()
-            << SLANG_MINIMUM_TARGET_API
-            << (SP.minAPI - 1)
-            << SP.name;
-        valid = false;
-      }
+    static const char KernelContextUnqualifiedTypeName[] =
+        "const struct rs_kernel_context_t *";
+    static const char KernelContextTypeName[] = "rs_kernel_context";
 
-      mSpecialParameterSignatureMetadata |= SP.bitval;
-      if (SpecialParameterIdx < LastSpecialParameterIdx) {
-        Context->ReportError(PVD->getLocation(),
-                             "In compute kernel %0(), parameter '%1' must "
-                             "be defined before parameter '%2'.")
-            << FD->getName()
-            << SP.name
-            << specialParameterTable[LastSpecialParameterIdx].name;
-        valid = false;
-      }
-      LastSpecialParameterIdx = SpecialParameterIdx;
+    // If the type is rs_context, it should have been named "context" and classified
+    // as a special parameter.
+    if (SpecialParameterIdx < 0 && UT.getAsString() == KernelContextUnqualifiedTypeName) {
+      Context->ReportError(
+          PVD->getLocation(),
+          "The special parameter of type '%0' must be called "
+          "'context' instead of '%1'.")
+          << KernelContextTypeName << ParamName;
+      SpecialParameterIdx = lookupSpecialParameter("context");
+    }
 
-      // Ensure that all SPK_INT special parameters have the same type.
-      if (SP.kind == SPK_INT) {
-        clang::QualType SpecialParameterType = PVD->getType();
-        if (FirstIntSpecialParameterIdx >= 0) {
-          if (SpecialParameterType != FirstIntSpecialParameterType) {
-            Context->ReportError(PVD->getLocation(),
-                                 "Parameters '%0' and '%1' must be of the same type. "
-                                 "'%0' is of type '%2' while '%1' is of type '%3'.")
-                << specialParameterTable[FirstIntSpecialParameterIdx].name
-                << SP.name
-                << FirstIntSpecialParameterType.getAsString()
-                << SpecialParameterType.getAsString();
-            valid = false;
-          }
-        } else {
-          FirstIntSpecialParameterIdx = SpecialParameterIdx;
-          FirstIntSpecialParameterType = SpecialParameterType;
-        }
-      }
-    } else {
-      // It's not a special parameter.
+    // If it's not a special parameter, check that it appears before any special
+    // parameter.
+    if (SpecialParameterIdx < 0) {
       if (*IndexOfFirstSpecialParameter < NumParams) {
         Context->ReportError(PVD->getLocation(),
                              "In compute kernel %0(), parameter '%1' cannot "
-                             "appear after any of the (%2) parameters.")
+                             "appear after any of the special parameters (%2).")
             << FD->getName() << ParamName << listSpecialParameters(Context->getTargetAPI());
         valid = false;
       }
       continue;
     }
-    // Validate the data type of the special parameter.
-    switch (specialParameterTable[SpecialParameterIdx].kind) {
-      case SPK_INT: {
-        clang::QualType QT = PVD->getType().getCanonicalType();
-        clang::QualType UT = QT.getUnqualifiedType();
-        if (UT != C.UnsignedIntTy && UT != C.IntTy) {
-          Context->ReportError(PVD->getLocation(),
-                               "Parameter '%0' must be of type 'int' or "
-                               "'unsigned int'. It is of type '%1'.")
-              << ParamName << PVD->getType().getAsString();
-          valid = false;
-        }
-        break;
-      }
-      case SPK_CTXT: {
-        static const char ExpectedTypeNameMatch[] = "const struct rs_kernel_context_t *";
-        static const char ExpectedTypeNamePrint[] = "rs_kernel_context";
-        clang::QualType QT = PVD->getType().getCanonicalType();
-        clang::QualType UT = QT.getUnqualifiedType();
-        if (UT.getAsString() != ExpectedTypeNameMatch) {
-          Context->ReportError(PVD->getLocation(),
-                               "Parameter '%0' must be of type '%1'. "
-                               "It is of type '%2'.")
-              << ParamName << ExpectedTypeNamePrint << PVD->getType().getAsString();
-          valid = false;
-        }
-        break;
-      }
-      default:
-        slangAssert(!"Unexpected special parameter type");
+
+    const SpecialParameter &SP = specialParameterTable[SpecialParameterIdx];
+
+    // Verify that this special parameter is OK for the current API level.
+    if (Context->getTargetAPI() < SP.minAPI) {
+      Context->ReportError(PVD->getLocation(),
+                           "Compute kernel %0() targeting SDK levels "
+                           "%1-%2 may not use special parameter '%3'.")
+          << FD->getName() << SLANG_MINIMUM_TARGET_API << (SP.minAPI - 1)
+          << SP.name;
+      valid = false;
     }
+
+    // Check that the order of the special parameters is correct.
+    if (SpecialParameterIdx < LastSpecialParameterIdx) {
+      Context->ReportError(
+          PVD->getLocation(),
+          "In compute kernel %0(), special parameter '%1' must "
+          "be defined before special parameter '%2'.")
+          << FD->getName() << SP.name
+          << specialParameterTable[LastSpecialParameterIdx].name;
+      valid = false;
+    }
+
+    // Validate the data type of the special parameter.
+    switch (SP.kind) {
+    case SPK_LOCATION: {
+      // Location special parameters can only be int or uint.
+      if (UT != C.UnsignedIntTy && UT != C.IntTy) {
+        Context->ReportError(PVD->getLocation(),
+                             "Special parameter '%0' must be of type 'int' or "
+                             "'unsigned int'. It is of type '%1'.")
+            << ParamName << Type.getAsString();
+        valid = false;
+      }
+
+      // Ensure that all location special parameters have the same type.
+      if (FirstLocationSpecialParameterIdx >= 0) {
+        if (Type != FirstLocationSpecialParameterType) {
+          Context->ReportError(
+              PVD->getLocation(),
+              "Special parameters '%0' and '%1' must be of the same type. "
+              "'%0' is of type '%2' while '%1' is of type '%3'.")
+              << specialParameterTable[FirstLocationSpecialParameterIdx].name
+              << SP.name << FirstLocationSpecialParameterType.getAsString()
+              << Type.getAsString();
+          valid = false;
+        }
+      } else {
+        FirstLocationSpecialParameterIdx = SpecialParameterIdx;
+        FirstLocationSpecialParameterType = Type;
+      }
+    } break;
+    case SPK_CONTEXT: {
+      // Check that variables named "context" are of type rs_context.
+      if (UT.getAsString() != KernelContextUnqualifiedTypeName) {
+        Context->ReportError(PVD->getLocation(),
+                             "Special parameter '%0' must be of type '%1'. "
+                             "It is of type '%2'.")
+            << ParamName << KernelContextTypeName
+            << Type.getAsString();
+        valid = false;
+      }
+    } break;
+    default:
+      slangAssert(!"Unexpected special parameter type");
+    }
+
+    // We should not be invoked if two parameters of the same name are present.
+    slangAssert(!(mSpecialParameterSignatureMetadata & SP.bitval));
+    mSpecialParameterSignatureMetadata |= SP.bitval;
+
+    LastSpecialParameterIdx = SpecialParameterIdx;
     // If this is the first time we find a special parameter, save it.
     if (*IndexOfFirstSpecialParameter >= NumParams) {
       *IndexOfFirstSpecialParameter = i;
diff --git a/slang_rs_export_foreach.h b/slang_rs_export_foreach.h
index 54b1303..581d8a1 100644
--- a/slang_rs_export_foreach.h
+++ b/slang_rs_export_foreach.h
@@ -86,9 +86,9 @@
   bool validateAndConstructKernelParams(RSContext *Context,
                                         const clang::FunctionDecl *FD);
 
-  bool validateSpecialParameters(RSContext *Context,
-                                 const clang::FunctionDecl *FD,
-                                 size_t *IndexOfFirstSpecialParameter);
+  bool processSpecialParameters(RSContext *Context,
+                                const clang::FunctionDecl *FD,
+                                size_t *IndexOfFirstSpecialParameter);
 
   bool setSignatureMetadata(RSContext *Context,
                             const clang::FunctionDecl *FD);
diff --git a/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs b/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs
index 34a0a7c..cabf40e 100644
--- a/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs
+++ b/tests/F_ctxt_wrong_api/F_ctxt_wrong_api.rs
@@ -2,6 +2,6 @@
 #pragma version(1)
 #pragma rs java_package_name(foo)
 
-int RS_KERNEL good(int in, rs_kernel_context ctxt) {
+int RS_KERNEL good(int in, rs_kernel_context context) {
   return 0;
 }
diff --git a/tests/F_ctxt_wrong_name/context.rs b/tests/F_ctxt_wrong_name/context.rs
new file mode 100644
index 0000000..d39fbed
--- /dev/null
+++ b/tests/F_ctxt_wrong_name/context.rs
@@ -0,0 +1,7 @@
+// -target-api 23
+#pragma version(1)
+#pragma rs java_package_name(foo)
+
+int RS_KERNEL bad(int in, uint32_t x, rs_kernel_context ct) {
+  return 0;
+}
diff --git a/tests/F_ctxt_wrong_name/stderr.txt.expect b/tests/F_ctxt_wrong_name/stderr.txt.expect
new file mode 100644
index 0000000..b102ee6
--- /dev/null
+++ b/tests/F_ctxt_wrong_name/stderr.txt.expect
@@ -0,0 +1,2 @@
+context.rs:5:57: error: The special parameter of type 'rs_kernel_context' must be called 'context' instead of 'ct'.
+context.rs:5:57: error: In compute kernel bad(), special parameter 'context' must be defined before special parameter 'x'.
diff --git a/tests/F_ctxt_wrong_name/stdout.txt.expect b/tests/F_ctxt_wrong_name/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_ctxt_wrong_name/stdout.txt.expect
diff --git a/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs b/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs
index 7226094..29298ff 100644
--- a/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs
+++ b/tests/F_ctxt_wrong_place/F_ctxt_wrong_place.rs
@@ -2,10 +2,10 @@
 #pragma version(1)
 #pragma rs java_package_name(foo)
 
-int RS_KERNEL good(int in, rs_kernel_context ctxt, uint32_t x) {
+int RS_KERNEL good(int in, rs_kernel_context context, uint32_t x) {
   return 0;
 }
 
-int RS_KERNEL bad(int in, uint32_t x, rs_kernel_context ctxt) {
+int RS_KERNEL bad(int in, uint32_t x, rs_kernel_context context) {
   return 0;
 }
diff --git a/tests/F_ctxt_wrong_place/stderr.txt.expect b/tests/F_ctxt_wrong_place/stderr.txt.expect
index 60c2b70..70b3f6e 100644
--- a/tests/F_ctxt_wrong_place/stderr.txt.expect
+++ b/tests/F_ctxt_wrong_place/stderr.txt.expect
@@ -1 +1 @@
-F_ctxt_wrong_place.rs:9:57: error: In compute kernel bad(), parameter 'ctxt' must be defined before parameter 'x'.
+F_ctxt_wrong_place.rs:9:57: error: In compute kernel bad(), special parameter 'context' must be defined before special parameter 'x'.
diff --git a/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs b/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs
index 358dae4..11d2433 100644
--- a/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs
+++ b/tests/F_ctxt_wrong_type/F_ctxt_wrong_type.rs
@@ -2,14 +2,14 @@
 #pragma version(1)
 #pragma rs java_package_name(foo)
 
-int RS_KERNEL good1(int in, rs_kernel_context ctxt) {
+int RS_KERNEL good1(int in, rs_kernel_context context) {
   return 0;
 }
 
-int RS_KERNEL good2(int in, const rs_kernel_context ctxt) {
+int RS_KERNEL good2(int in, const rs_kernel_context context) {
   return 0;
 }
 
-int RS_KERNEL bad3(int in, const rs_kernel_context *ctxt) {
+int RS_KERNEL bad3(int in, const rs_kernel_context *context) {
   return 0;
 }
diff --git a/tests/F_ctxt_wrong_type/stderr.txt.expect b/tests/F_ctxt_wrong_type/stderr.txt.expect
index 54cf641..d6de8fa 100644
--- a/tests/F_ctxt_wrong_type/stderr.txt.expect
+++ b/tests/F_ctxt_wrong_type/stderr.txt.expect
@@ -1 +1 @@
-F_ctxt_wrong_type.rs:13:53: error: Parameter 'ctxt' must be of type 'rs_kernel_context'. It is of type 'const rs_kernel_context *'.
+F_ctxt_wrong_type.rs:13:53: error: Special parameter 'context' must be of type 'rs_kernel_context'. It is of type 'const rs_kernel_context *'.
diff --git a/tests/F_root_compute_int_in/stderr.txt.expect b/tests/F_root_compute_int_in/stderr.txt.expect
index cf6eabe..13925df 100644
--- a/tests/F_root_compute_int_in/stderr.txt.expect
+++ b/tests/F_root_compute_int_in/stderr.txt.expect
@@ -1,2 +1,2 @@
-root_compute_int_in.rs:4:21: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'in' is of type: 'const int'
+root_compute_int_in.rs:4:21: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'in' is of type: 'const int'
 root_compute_int_in.rs:4:6: error: Compute kernel root() must have at least one parameter for in or out
diff --git a/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect b/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
index 04c7735..a113ce4 100644
--- a/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
+++ b/tests/F_root_compute_non_ptr_usrData/stderr.txt.expect
@@ -1 +1 @@
-root_compute_non_ptr_usrData.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'usrData' is of type: 'const int'
+root_compute_non_ptr_usrData.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'usrData' is of type: 'const int'
diff --git a/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect b/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
index ba7eecb..9b4af29 100644
--- a/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
+++ b/tests/F_root_compute_non_uint32_t_xyzar/stderr.txt.expect
@@ -1,6 +1,6 @@
-root_compute_non_uint32_t_xyzar.rs:5:17: error: Parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'.
-root_compute_non_uint32_t_xyzar.rs:5:26: error: Parameters 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'.
-root_compute_non_uint32_t_xyzar.rs:5:26: error: Parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'.
-root_compute_non_uint32_t_xyzar.rs:5:36: error: Parameters 'x' and 'z' must be of the same type. 'x' is of type 'short' while 'z' is of type 'double'.
-root_compute_non_uint32_t_xyzar.rs:5:36: error: Parameter 'z' must be of type 'int' or 'unsigned int'. It is of type 'double'.
-root_compute_non_uint32_t_xyzar.rs:5:45: error: In compute kernel root(), parameter 'ar' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_non_uint32_t_xyzar.rs:5:17: error: Special parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'.
+root_compute_non_uint32_t_xyzar.rs:5:26: error: Special parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'.
+root_compute_non_uint32_t_xyzar.rs:5:26: error: Special parameters 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'.
+root_compute_non_uint32_t_xyzar.rs:5:36: error: Special parameter 'z' must be of type 'int' or 'unsigned int'. It is of type 'double'.
+root_compute_non_uint32_t_xyzar.rs:5:36: error: Special parameters 'x' and 'z' must be of the same type. 'x' is of type 'short' while 'z' is of type 'double'.
+root_compute_non_uint32_t_xyzar.rs:5:45: error: In compute kernel root(), parameter 'ar' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
diff --git a/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect b/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect
index bdd564b..9678fac 100644
--- a/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect
+++ b/tests/F_root_compute_non_uint32_t_xyzwar/stderr.txt.expect
@@ -1,7 +1,7 @@
-root_compute_non_uint32_t_xyzwar.rs:6:17: error: Parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'.
-root_compute_non_uint32_t_xyzwar.rs:6:26: error: Parameters 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'.
-root_compute_non_uint32_t_xyzwar.rs:6:26: error: Parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'.
-root_compute_non_uint32_t_xyzwar.rs:6:36: error: Parameters 'x' and 'z' must be of the same type. 'x' is of type 'short' while 'z' is of type 'double'.
-root_compute_non_uint32_t_xyzwar.rs:6:36: error: Parameter 'z' must be of type 'int' or 'unsigned int'. It is of type 'double'.
-root_compute_non_uint32_t_xyzwar.rs:6:44: error: In compute kernel root(), parameter 'w' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
-root_compute_non_uint32_t_xyzwar.rs:6:53: error: In compute kernel root(), parameter 'ar' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_non_uint32_t_xyzwar.rs:6:17: error: Special parameter 'x' must be of type 'int' or 'unsigned int'. It is of type 'short'.
+root_compute_non_uint32_t_xyzwar.rs:6:26: error: Special parameter 'y' must be of type 'int' or 'unsigned int'. It is of type 'float'.
+root_compute_non_uint32_t_xyzwar.rs:6:26: error: Special parameters 'x' and 'y' must be of the same type. 'x' is of type 'short' while 'y' is of type 'float'.
+root_compute_non_uint32_t_xyzwar.rs:6:36: error: Special parameter 'z' must be of type 'int' or 'unsigned int'. It is of type 'double'.
+root_compute_non_uint32_t_xyzwar.rs:6:36: error: Special parameters 'x' and 'z' must be of the same type. 'x' is of type 'short' while 'z' is of type 'double'.
+root_compute_non_uint32_t_xyzwar.rs:6:44: error: In compute kernel root(), parameter 'w' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
+root_compute_non_uint32_t_xyzwar.rs:6:53: error: In compute kernel root(), parameter 'ar' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
diff --git a/tests/F_root_compute_really_bad/stderr.txt.expect b/tests/F_root_compute_really_bad/stderr.txt.expect
index d737ef0..7d10dcc 100644
--- a/tests/F_root_compute_really_bad/stderr.txt.expect
+++ b/tests/F_root_compute_really_bad/stderr.txt.expect
@@ -1,17 +1,17 @@
 root_compute_really_bad.rs:4:5: error: Compute kernel root() is required to return a void type
-root_compute_really_bad.rs:5:31: error: In compute kernel root(), parameter 'x' must be defined before parameter 'y'.
-root_compute_really_bad.rs:6:19: error: In compute kernel root(), parameter 'extra1' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
-root_compute_really_bad.rs:6:36: error: In compute kernel root(), parameter 'extra2' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
-root_compute_really_bad.rs:4:14: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'ain' is of type: 'int'
-root_compute_really_bad.rs:4:23: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'aout' is of type: 'int'
-root_compute_really_bad.rs:4:33: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'usrData' is of type: 'int'
-root_compute_really_bad.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'x1' is of type: 'float'
-root_compute_really_bad.rs:4:59: error: Compute kernel root() cannot have non-pointer parameters besides ('ctxt', 'x', 'y', 'z'). Parameter 'y1' is of type: 'double'
+root_compute_really_bad.rs:5:31: error: In compute kernel root(), special parameter 'x' must be defined before special parameter 'y'.
+root_compute_really_bad.rs:6:19: error: In compute kernel root(), parameter 'extra1' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
+root_compute_really_bad.rs:6:36: error: In compute kernel root(), parameter 'extra2' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
+root_compute_really_bad.rs:4:14: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'ain' is of type: 'int'
+root_compute_really_bad.rs:4:23: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'aout' is of type: 'int'
+root_compute_really_bad.rs:4:33: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'usrData' is of type: 'int'
+root_compute_really_bad.rs:4:48: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'x1' is of type: 'float'
+root_compute_really_bad.rs:4:59: error: Compute kernel root() cannot have non-pointer parameters besides special parameters ('context', 'x', 'y', 'z'). Parameter 'y1' is of type: 'double'
 root_compute_really_bad.rs:4:5: error: Compute kernel root() must have at least one parameter for in or out
 root_compute_really_bad.rs:10:44: error: Compute kernel root2() can only have one non-const pointer parameter. Parameters 'ain' and 'usrData' are both non-const.
 root_compute_really_bad.rs:10:66: error: Unexpected parameter 'x1' for compute kernel root2()
 root_compute_really_bad.rs:11:26: error: Unexpected parameter 'y1' for compute kernel root2()
-root_compute_really_bad.rs:16:38: error: In compute kernel root_kernel(), parameter 'x' must be defined before parameter 'y'.
-root_compute_really_bad.rs:16:50: error: In compute kernel root_kernel(), parameter 'extra1' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
-root_compute_really_bad.rs:16:67: error: In compute kernel root_kernel(), parameter 'extra2' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_really_bad.rs:16:38: error: In compute kernel root_kernel(), special parameter 'x' must be defined before special parameter 'y'.
+root_compute_really_bad.rs:16:50: error: In compute kernel root_kernel(), parameter 'extra1' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
+root_compute_really_bad.rs:16:67: error: In compute kernel root_kernel(), parameter 'extra2' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
 root_compute_really_bad.rs:15:31: error: Compute kernel root_kernel() cannot have parameter 'aout' of pointer type: 'int *'
diff --git a/tests/F_root_compute_too_many_args/stderr.txt.expect b/tests/F_root_compute_too_many_args/stderr.txt.expect
index dbb0500..8afe8bc 100644
--- a/tests/F_root_compute_too_many_args/stderr.txt.expect
+++ b/tests/F_root_compute_too_many_args/stderr.txt.expect
@@ -1,2 +1,2 @@
-root_compute_too_many_args.rs:6:20: error: In compute kernel root(), parameter 'extra1' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
-root_compute_too_many_args.rs:6:37: error: In compute kernel root(), parameter 'extra2' cannot appear after any of the ('ctxt', 'x', 'y', 'z') parameters.
+root_compute_too_many_args.rs:6:20: error: In compute kernel root(), parameter 'extra1' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
+root_compute_too_many_args.rs:6:37: error: In compute kernel root(), parameter 'extra2' cannot appear after any of the special parameters ('context', 'x', 'y', 'z').
diff --git a/tests/F_z_wrong_api/stderr.txt.expect b/tests/F_z_wrong_api/stderr.txt.expect
index 9553acd..0a64501 100644
--- a/tests/F_z_wrong_api/stderr.txt.expect
+++ b/tests/F_z_wrong_api/stderr.txt.expect
@@ -1 +1 @@
-F_z_wrong_api.rs:5:60: error: Compute kernel bad() targeting SDK levels 11-22 may not use parameter 'z'.
+F_z_wrong_api.rs:5:60: error: Compute kernel bad() targeting SDK levels 11-22 may not use special parameter 'z'.
diff --git a/tests/P_all_api_23/all23.rs b/tests/P_all_api_23/all23.rs
index 08711bd..7d2acc9 100644
--- a/tests/P_all_api_23/all23.rs
+++ b/tests/P_all_api_23/all23.rs
@@ -4702,7 +4702,7 @@
 char buf4679[200];
 char buf4680[200];
 
-void RS_KERNEL test(int in, rs_kernel_context ctxt) {
+void RS_KERNEL test(int in, rs_kernel_context context) {
     *(uchar*)buf0 = abs(*(char*)buf1);
     *(uchar2*)buf2 = abs(*(char2*)buf3);
     *(uchar3*)buf4 = abs(*(char3*)buf5);
@@ -5901,19 +5901,19 @@
     rsForEach(*(rs_script*)buf3173, *(rs_allocation*)buf3174, *(rs_allocation*)buf3175);
     *(float*)buf3176 = rsFrac(*(float*)buf3177);
     *(rs_allocation*)buf3178 = rsGetAllocation((const void*) buf3179);
-    *(uint32_t*)buf3180 = rsGetArray0(ctxt);
-    *(uint32_t*)buf3181 = rsGetArray1(ctxt);
-    *(uint32_t*)buf3182 = rsGetArray2(ctxt);
-    *(uint32_t*)buf3183 = rsGetArray3(ctxt);
-    *(uint32_t*)buf3184 = rsGetDimArray0(ctxt);
-    *(uint32_t*)buf3185 = rsGetDimArray1(ctxt);
-    *(uint32_t*)buf3186 = rsGetDimArray2(ctxt);
-    *(uint32_t*)buf3187 = rsGetDimArray3(ctxt);
-    *(bool*)buf3188 = rsGetDimHasFaces(ctxt);
-    *(uint32_t*)buf3189 = rsGetDimLod(ctxt);
-    *(uint32_t*)buf3190 = rsGetDimX(ctxt);
-    *(uint32_t*)buf3191 = rsGetDimY(ctxt);
-    *(uint32_t*)buf3192 = rsGetDimZ(ctxt);
+    *(uint32_t*)buf3180 = rsGetArray0(context);
+    *(uint32_t*)buf3181 = rsGetArray1(context);
+    *(uint32_t*)buf3182 = rsGetArray2(context);
+    *(uint32_t*)buf3183 = rsGetArray3(context);
+    *(uint32_t*)buf3184 = rsGetDimArray0(context);
+    *(uint32_t*)buf3185 = rsGetDimArray1(context);
+    *(uint32_t*)buf3186 = rsGetDimArray2(context);
+    *(uint32_t*)buf3187 = rsGetDimArray3(context);
+    *(bool*)buf3188 = rsGetDimHasFaces(context);
+    *(uint32_t*)buf3189 = rsGetDimLod(context);
+    *(uint32_t*)buf3190 = rsGetDimX(context);
+    *(uint32_t*)buf3191 = rsGetDimY(context);
+    *(uint32_t*)buf3192 = rsGetDimZ(context);
     *(float*)buf3193 = rsGetDt();
     *(const void**)buf3194 = rsGetElementAt(*(rs_allocation*)buf3195, *(uint32_t*)buf3196);
     *(const void**)buf3197 = rsGetElementAt(*(rs_allocation*)buf3198, *(uint32_t*)buf3199, *(uint32_t*)buf3200);
@@ -6053,8 +6053,8 @@
     *(uchar*)buf3734 = rsGetElementAtYuv_uchar_U(*(rs_allocation*)buf3735, *(uint32_t*)buf3736, *(uint32_t*)buf3737);
     *(uchar*)buf3738 = rsGetElementAtYuv_uchar_V(*(rs_allocation*)buf3739, *(uint32_t*)buf3740, *(uint32_t*)buf3741);
     *(uchar*)buf3742 = rsGetElementAtYuv_uchar_Y(*(rs_allocation*)buf3743, *(uint32_t*)buf3744, *(uint32_t*)buf3745);
-    *(rs_allocation_cubemap_face*)buf3746 = rsGetFace(ctxt);
-    *(uint32_t*)buf3747 = rsGetLod(ctxt);
+    *(rs_allocation_cubemap_face*)buf3746 = rsGetFace(context);
+    *(uint32_t*)buf3747 = rsGetLod(context);
     *(bool*)buf3748 = rsIsObject(*(rs_element*)buf3749);
     *(bool*)buf3750 = rsIsObject(*(rs_type*)buf3751);
     *(bool*)buf3752 = rsIsObject(*(rs_allocation*)buf3753);