Handle opaque pointers in image specialization (#863)

Contributes to #816

* Image specialization now handles both transparent and opaque pointers
  * Much of the code can be removed after moving fully to opaque
    pointers
  * Doesn't use InferTypes because the pass's traversal is necessary and would
    simply be repeated
  * Specialized builtin functions are now remangled from an updated type instead of having a
    suffix tacked on
* Fixed some image query functions to support mangled struct names
* Fixed some builtin demangling
* Changed how opaque pointers is disabled
  * added a new command line option to control it
  * sets the code gen option
  * remove the command line parsing
diff --git a/lib/Builtins.cpp b/lib/Builtins.cpp
index 5c00059..5871d7d 100644
--- a/lib/Builtins.cpp
+++ b/lib/Builtins.cpp
@@ -233,11 +233,13 @@
   while (pos < mangled_name_len) {
     ParamTypeInfo type_info;
     if (mangled_name[pos] == 'S') {
-      // handle duplicate param_type
-      if (mangled_name[pos + 1] != '_') {
+      // handle duplicate param_type. Comes in two flavours:
+      // S_ and S#_.
+      char p1 = mangled_name[pos + 1];
+      if (p1 != '_' && (mangled_name[pos + 2] != '_')) {
         return false;
       }
-      pos += 2;
+      pos += p1 == '_' ? 2 : 3;
       if (params_.empty()) {
         return false;
       }