Don't use anonymous literal structures for RS object types.

Bug: 22926131

Using an anonymous structure type prevents us from being able to use
LLVM to determine the actual typename. This is problematic, because
there are some cases where bcc needs to be able to detect/act on RS
object types. Giving each of these structures a legitimate name has no
impact on the generated code (since we are already using typedefs).
This change is also safe for targeting prior Android releases with our
toolchain.

This change also adjusts the API generator to ensure that we can
generate relevant code/docs/tests for handling RS objects. A new
TypeKind is added for RS_OBJECT, instead of using SIMPLE.

Change-Id: Iaff928f5821af66cfc9b3aea2ff5549d0c8a9408
diff --git a/api/GenerateDocumentation.cpp b/api/GenerateDocumentation.cpp
index 9d399d4..41f85cb 100644
--- a/api/GenerateDocumentation.cpp
+++ b/api/GenerateDocumentation.cpp
@@ -306,7 +306,8 @@
     writeSummaryTable(file, &functionStream, "Functions", deprecatedSelector, labelAsHeader);
 }
 
-static void writeHtmlVersionTag(GeneratedFile* file, VersionInfo info) {
+static void writeHtmlVersionTag(GeneratedFile* file, VersionInfo info,
+                                bool addSpacing) {
     ostringstream stream;
     if (info.intSize == 32) {
         stream << "When compiling for 32 bits. ";
@@ -334,9 +335,13 @@
         }
         stream << "</a>";
     }
-    const string s = stream.str();
+    string s = stream.str();
+    // Remove any trailing whitespace
+    while (s.back() == ' ') {
+        s.pop_back();
+    }
     if (!s.empty()) {
-        *file << "    " << s << "\n";
+        *file << (addSpacing ? "    " : "") << s << "\n";
     }
 }
 
@@ -345,16 +350,22 @@
         case SIMPLE: {
             Type* type = spec->getType();
             *file << "<p>A typedef of: " << spec->getSimpleType()
-                  << makeAttributeTag(spec->getAttribute(), "", type->deprecated(),
+                  << makeAttributeTag(spec->getAttribute(), "", type->getDeprecatedApiLevel(),
                                       type->getDeprecatedMessage())
                   << "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
-            writeHtmlVersionTag(file, spec->getVersionInfo());
+            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
+            *file << "</p>\n";
+            break;
+        }
+        case RS_OBJECT: {
+            *file << "<p>";
+            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
             *file << "</p>\n";
             break;
         }
         case ENUM: {
             *file << "<p>An enum with the following values:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n";
-            writeHtmlVersionTag(file, spec->getVersionInfo());
+            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
             *file << "</p>\n";
 
             *file << "  <table class='jd-tagtable'><tbody>\n";
@@ -372,7 +383,7 @@
         }
         case STRUCT: {
             *file << "<p>A structure with the following fields:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
-            writeHtmlVersionTag(file, spec->getVersionInfo());
+            writeHtmlVersionTag(file, spec->getVersionInfo(), false);
             *file << "</p>\n";
 
             *file << "  <table class='jd-tagtable'><tbody>\n";
@@ -394,7 +405,7 @@
 static void writeDetailedConstantSpecification(GeneratedFile* file, ConstantSpecification* c) {
     *file << "      <tr><td>";
     *file << "Value: " << c->getValue() << "\n";
-    writeHtmlVersionTag(file, c->getVersionInfo());
+    writeHtmlVersionTag(file, c->getVersionInfo(), true);
     *file << "      </td></tr>\n";
     *file << "<br/>\n";
 }
@@ -557,7 +568,7 @@
         *file << "      <tr>\n";
         *file << "        <td>" << i.second.htmlDeclaration << "</td>\n";
         *file << "        <td>";
-        writeHtmlVersionTag(file, i.second.info);
+        writeHtmlVersionTag(file, i.second.info, true);
         *file << "        </td>\n";
         *file << "      </tr>\n";
     }
diff --git a/api/GenerateHeaderFiles.cpp b/api/GenerateHeaderFiles.cpp
index e908ff1..aac7ecb 100644
--- a/api/GenerateHeaderFiles.cpp
+++ b/api/GenerateHeaderFiles.cpp
@@ -138,6 +138,9 @@
         case SIMPLE:
             *file << spec.getSimpleType() << attribute;
             break;
+        case RS_OBJECT:
+            *file << "struct " << typeName << " _RS_OBJECT_DECL" << attribute;
+            break;
         case ENUM: {
             *file << "enum" << attribute << " ";
             const string name = spec.getEnumName();
diff --git a/api/GenerateStubsWhiteList.cpp b/api/GenerateStubsWhiteList.cpp
index ea18eed..9b4297d 100644
--- a/api/GenerateStubsWhiteList.cpp
+++ b/api/GenerateStubsWhiteList.cpp
@@ -70,21 +70,14 @@
             }
             switch (spec->getKind()) {
                 case SIMPLE: {
-                    /* For simple typedefs, replace it unless it's the special case of _RS_HANDLE
-                     * which is a macro of a struct.
-                     */
-                    const string s = spec->getSimpleType();
-                    if (s != "_RS_HANDLE") {
-                        return s;
-                    }
+                    return spec->getSimpleType();
+                }
+                case RS_OBJECT: {
+                    // Do nothing for RS object types.
                     break;
                 }
                 case STRUCT: {
-                    const string s = spec->getStructName();
-                    if (!s.empty()) {
-                        return s;
-                    }
-                    break;
+                    return spec->getStructName();
                 }
                 case ENUM:
                     // Do nothing
diff --git a/api/Specification.cpp b/api/Specification.cpp
index 7862d31..f02e429 100644
--- a/api/Specification.cpp
+++ b/api/Specification.cpp
@@ -378,6 +378,9 @@
         spec->mKind = SIMPLE;
         spec->mSimpleType = scanner->getValue();
     }
+    if (scanner->findOptionalTag("rs_object:")) {
+        spec->mKind = RS_OBJECT;
+    }
     if (scanner->findOptionalTag("struct:")) {
         spec->mKind = STRUCT;
         spec->mStructName = scanner->getValue();
diff --git a/api/Specification.h b/api/Specification.h
index df3c55c..87969a6 100644
--- a/api/Specification.h
+++ b/api/Specification.h
@@ -271,6 +271,7 @@
 
 enum TypeKind {
     SIMPLE,
+    RS_OBJECT,
     STRUCT,
     ENUM,
 };
diff --git a/api/rs_graphics.spec b/api/rs_graphics.spec
index af41a28..f5b8096 100644
--- a/api/rs_graphics.spec
+++ b/api/rs_graphics.spec
@@ -117,7 +117,7 @@
 type: rs_font
 version: 9 22
 size: 32
-simple: _RS_HANDLE
+rs_object:
 deprecated: 22
 summary: Handle to a Font
 description:
@@ -129,7 +129,7 @@
 type: rs_mesh
 version: 9 22
 size: 32
-simple: _RS_HANDLE
+rs_object:
 deprecated: 22
 summary: Handle to a Mesh
 description:
@@ -140,7 +140,7 @@
 type: rs_program_fragment
 version: 9 22
 size: 32
-simple: _RS_HANDLE
+rs_object:
 deprecated: 22
 summary: Handle to a ProgramFragment
 description:
@@ -151,7 +151,7 @@
 type: rs_program_vertex
 version: 9 22
 size: 32
-simple: _RS_HANDLE
+rs_object:
 deprecated: 22
 summary: Handle to a ProgramVertex
 description:
@@ -162,7 +162,7 @@
 type: rs_program_raster
 version: 9 22
 size: 32
-simple: _RS_HANDLE
+rs_object:
 deprecated: 22
 summary: Handle to a ProgramRaster
 description:
@@ -173,7 +173,7 @@
 type: rs_program_store
 version: 9 22
 size: 32
-simple: _RS_HANDLE
+rs_object:
 deprecated: 22
 summary: Handle to a ProgramStore
 description:
diff --git a/api/rs_object_types.spec b/api/rs_object_types.spec
index 092ef99..d9f20d7 100644
--- a/api/rs_object_types.spec
+++ b/api/rs_object_types.spec
@@ -24,13 +24,13 @@
 
  // Opaque handle to a RenderScript object. Do not use this directly.
  #ifndef __LP64__
- #define _RS_HANDLE \
- struct {\
+ #define _RS_OBJECT_DECL \
+ {\
    const int* const p;\
  } __attribute__((packed, aligned(4)))
  #else
- #define _RS_HANDLE \
- struct {\
+ #define _RS_OBJECT_DECL \
+ {\
    const long* const p;\
    const long* const r;\
    const long* const v1;\
@@ -40,7 +40,7 @@
 end:
 
 type: rs_element
-simple: _RS_HANDLE
+rs_object:
 summary: Handle to an element
 description:
  An opaque handle to a RenderScript element.
@@ -49,7 +49,7 @@
 end:
 
 type: rs_type
-simple: _RS_HANDLE
+rs_object:
 summary: Handle to a Type
 description:
  An opaque handle to a RenderScript type.
@@ -58,7 +58,7 @@
 end:
 
 type: rs_allocation
-simple: _RS_HANDLE
+rs_object:
 summary: Handle to an allocation
 description:
  An opaque handle to a RenderScript allocation.
@@ -67,7 +67,7 @@
 end:
 
 type: rs_sampler
-simple: _RS_HANDLE
+rs_object:
 summary: Handle to a Sampler
 description:
  An opaque handle to a RenderScript sampler object.
@@ -76,7 +76,7 @@
 end:
 
 type: rs_script
-simple: _RS_HANDLE
+rs_object:
 summary: Handle to a Script
 description:
  An opaque handle to a RenderScript script object.