Generate __attribute__(deprecated) for deprecated APIs.

We allow also a custom deprecation message.

Change-Id: I297bed611c7fbbb34d41e7edd796557c9afe50da
diff --git a/api/GenerateDocumentation.cpp b/api/GenerateDocumentation.cpp
index b78edae..565f4fb 100644
--- a/api/GenerateDocumentation.cpp
+++ b/api/GenerateDocumentation.cpp
@@ -340,22 +340,26 @@
     }
 }
 
-static void writeDetailedTypeSpecification(GeneratedFile* file, const TypeSpecification* type) {
-    switch (type->getKind()) {
-        case SIMPLE:
-            *file << "<p>A typedef of: " << type->getSimpleType()
+static void writeDetailedTypeSpecification(GeneratedFile* file, const TypeSpecification* spec) {
+    switch (spec->getKind()) {
+        case SIMPLE: {
+            Type* type = spec->getType();
+            *file << "<p>A typedef of: " << spec->getSimpleType()
+                  << makeAttributeTag(spec->getAttribute(), "", type->deprecated(),
+                                      type->getDeprecatedMessage())
                   << "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
-            writeHtmlVersionTag(file, type->getVersionInfo());
+            writeHtmlVersionTag(file, spec->getVersionInfo());
             *file << "</p>\n";
             break;
+        }
         case ENUM: {
             *file << "<p>An enum with the following values:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\n";
-            writeHtmlVersionTag(file, type->getVersionInfo());
+            writeHtmlVersionTag(file, spec->getVersionInfo());
             *file << "</p>\n";
 
             *file << "  <table class='jd-tagtable'><tbody>\n";
-            const vector<string>& values = type->getValues();
-            const vector<string>& valueComments = type->getValueComments();
+            const vector<string>& values = spec->getValues();
+            const vector<string>& valueComments = spec->getValueComments();
             for (size_t i = 0; i < values.size(); i++) {
                 *file << "    <tr><th>" << values[i] << "</th><td>";
                 if (valueComments.size() > i) {
@@ -368,12 +372,12 @@
         }
         case STRUCT: {
             *file << "<p>A structure with the following fields:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
-            writeHtmlVersionTag(file, type->getVersionInfo());
+            writeHtmlVersionTag(file, spec->getVersionInfo());
             *file << "</p>\n";
 
             *file << "  <table class='jd-tagtable'><tbody>\n";
-            const vector<string>& fields = type->getFields();
-            const vector<string>& fieldComments = type->getFieldComments();
+            const vector<string>& fields = spec->getFields();
+            const vector<string>& fieldComments = spec->getFieldComments();
             for (size_t i = 0; i < fields.size(); i++) {
                 *file << "    <tr><th>" << fields[i] << "</th><td>";
                 if (fieldComments.size() > i && !fieldComments[i].empty()) {
diff --git a/api/GenerateHeaderFiles.cpp b/api/GenerateHeaderFiles.cpp
index 45cdba9..e908ff1 100644
--- a/api/GenerateHeaderFiles.cpp
+++ b/api/GenerateHeaderFiles.cpp
@@ -129,12 +129,17 @@
     const string& typeName = type->getName();
     const VersionInfo info = spec.getVersionInfo();
     writeVersionGuardStart(file, info, type->getFinalVersion());
+
+    const string attribute =
+                makeAttributeTag(spec.getAttribute(), "", type->getDeprecatedApiLevel(),
+                                 type->getDeprecatedMessage());
+    *file << "typedef ";
     switch (spec.getKind()) {
         case SIMPLE:
-            *file << "typedef " << spec.getSimpleType() << " " << typeName << ";\n";
+            *file << spec.getSimpleType() << attribute;
             break;
         case ENUM: {
-            *file << "typedef enum ";
+            *file << "enum" << attribute << " ";
             const string name = spec.getEnumName();
             if (!name.empty()) {
                 *file << name << " ";
@@ -154,11 +159,11 @@
                 }
                 *file << "\n";
             }
-            *file << "} " << typeName << ";\n";
+            *file << "}";
             break;
         }
         case STRUCT: {
-            *file << "typedef struct ";
+            *file << "struct" << attribute << " ";
             const string name = spec.getStructName();
             if (!name.empty()) {
                 *file << name << " ";
@@ -174,15 +179,12 @@
                 }
                 *file << "\n";
             }
-            *file << "} ";
-            const string attrib = spec.getAttrib();
-            if (!attrib.empty()) {
-                *file << attrib << " ";
-            }
-            *file << typeName << ";\n";
+            *file << "}";
             break;
         }
     }
+    *file << " " << typeName << ";\n";
+
     writeVersionGuardEnd(file, info);
     *file << "\n";
 }
@@ -213,20 +215,9 @@
         *file << "void";
     }
 
-    // Write the attribute.
-    *file << " __attribute__((";
-    const string attrib = spec.getAttribute();
-    if (attrib.empty()) {
-        *file << "overloadable";
-    } else if (attrib[0] == '=') {
-        /* If starts with an equal, we don't automatically add overloadable.
-         * This is because of the error we made defining rsUnpackColor8888().
-         */
-        *file << attrib.substr(1);
-    } else {
-        *file << attrib << ", overloadable";
-    }
-    *file << "))\n";
+    *file << makeAttributeTag(spec.getAttribute(), "overloadable",
+                              function->getDeprecatedApiLevel(), function->getDeprecatedMessage());
+    *file << "\n";
 
     // Write the function name.
     *file << "    " << permutation.getName() << "(";
diff --git a/api/Specification.cpp b/api/Specification.cpp
index a82fd1b..362aef2 100644
--- a/api/Specification.cpp
+++ b/api/Specification.cpp
@@ -225,7 +225,7 @@
 }
 
 Definition::Definition(const std::string& name)
-    : mName(name), mDeprecated(false), mHidden(false), mFinalVersion(-1) {
+    : mName(name), mDeprecatedApiLevel(0), mHidden(false), mFinalVersion(-1) {
 }
 
 void Definition::updateFinalVersion(const VersionInfo& info) {
@@ -247,8 +247,16 @@
         mHidden = true;
     }
     if (scanner->findOptionalTag("deprecated:")) {
-        mDeprecated = true;
-        mDeprecatedMessage = scanner->getValue();
+        string value = scanner->getValue();
+        size_t pComma = value.find(", ");
+        if (pComma != string::npos) {
+            mDeprecatedMessage = value.substr(pComma + 2);
+            value.erase(pComma);
+        }
+        sscanf(value.c_str(), "%i", &mDeprecatedApiLevel);
+        if (mDeprecatedApiLevel <= 0) {
+            scanner->error() << "deprecated entries should have a level > 0\n";
+        }
     }
     if (firstOccurence) {
         if (scanner->findTag("summary:")) {
@@ -380,9 +388,6 @@
             spec->mFields.push_back(s);
             spec->mFieldComments.push_back(comment);
         }
-        if (scanner->findOptionalTag("attrib:")) {
-            spec->mAttrib = scanner->getValue();
-        }
     }
     if (scanner->findOptionalTag("enum:")) {
         spec->mKind = ENUM;
@@ -395,6 +400,9 @@
             spec->mValueComments.push_back(comment);
         }
     }
+    if (scanner->findOptionalTag("attrib:")) {
+        spec->mAttribute = scanner->getValue();
+    }
     type->scanDocumentationTags(scanner, created, specFile);
 
     scanner->findTag("end:");
diff --git a/api/Specification.h b/api/Specification.h
index 9783310..1ec6973 100644
--- a/api/Specification.h
+++ b/api/Specification.h
@@ -141,7 +141,10 @@
 class Definition {
 protected:
     std::string mName;
-    bool mDeprecated;                       // True if this API should not be used
+    /* If greater than 0, this definition is deprecated.  It's the API level at which
+     * we added the deprecation warning.
+     */
+    int mDeprecatedApiLevel;
     std::string mDeprecatedMessage;         // Optional specific warning if the API is deprecated
     bool mHidden;                           // True if it should not be documented
     std::string mSummary;                   // A one-line description
@@ -153,7 +156,8 @@
     Definition(const std::string& name);
 
     std::string getName() const { return mName; }
-    bool deprecated() const { return mDeprecated; }
+    bool deprecated() const { return mDeprecatedApiLevel > 0; }
+    int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; }
     std::string getDeprecatedMessage() const { return mDeprecatedMessage; }
     bool hidden() const { return mHidden; }
     std::string getSummary() const { return mSummary; }
@@ -282,7 +286,7 @@
     std::string mStructName;                  // The name found after the struct keyword
     std::vector<std::string> mFields;         // One entry per struct field
     std::vector<std::string> mFieldComments;  // One entry per struct field
-    std::string mAttrib;                      // Some structures may have attributes
+    std::string mAttribute;                   // Some structures may have attributes
 
     // If mKind is ENUM:
     std::string mEnumName;                    // The name found after the enum keyword
@@ -297,7 +301,7 @@
     std::string getStructName() const { return mStructName; }
     const std::vector<std::string>& getFields() const { return mFields; }
     const std::vector<std::string>& getFieldComments() const { return mFieldComments; }
-    std::string getAttrib() const { return mAttrib; }
+    std::string getAttribute() const { return mAttribute; }
     std::string getEnumName() const { return mEnumName; }
     const std::vector<std::string>& getValues() const { return mValues; }
     const std::vector<std::string>& getValueComments() const { return mValueComments; }
diff --git a/api/Utilities.cpp b/api/Utilities.cpp
index 311d7c6..4268278 100644
--- a/api/Utilities.cpp
+++ b/api/Utilities.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <algorithm>
 #include <iostream>
 #include <sstream>
 
@@ -149,6 +150,48 @@
     return (double)l;
 }
 
+// Add the value to the stream, prefixed with a ", " if needed.
+static void addCommaSeparated(const string& value, ostringstream* stream, bool* needComma) {
+    if (value.empty()) {
+        return;
+    }
+    if (*needComma) {
+        *stream << ", ";
+    }
+    *stream << value;
+    *needComma = true;
+}
+
+string makeAttributeTag(const string& userAttribute, const string& additionalAttribute,
+                        int deprecatedApiLevel, const string& deprecatedMessage) {
+    ostringstream stream;
+    bool needComma = false;
+    if (userAttribute[0] == '=') {
+        /* If starts with an equal, we don't automatically add additionalAttribute.
+         * This is because of the error we made defining rsUnpackColor8888().
+         */
+        addCommaSeparated(userAttribute.substr(1), &stream, &needComma);
+    } else {
+        addCommaSeparated(userAttribute, &stream, &needComma);
+        addCommaSeparated(additionalAttribute, &stream, &needComma);
+    }
+    if (deprecatedApiLevel > 0) {
+        stream << "\n#if (defined(RS_VERSION) && (RS_VERSION >= " << deprecatedApiLevel << "))\n";
+        addCommaSeparated("deprecated", &stream, &needComma);
+        if (!deprecatedMessage.empty()) {
+            // Remove any @ that's used for generating documentation cross references.
+            string s = deprecatedMessage;
+            s.erase(std::remove(s.begin(), s.end(), '@'), s.end());
+            stream << "(\"" << s << "\")";
+        }
+        stream << "\n#endif\n";
+    }
+    if (stream.tellp() == 0) {
+        return "";
+    }
+    return " __attribute__((" + stream.str() + "))";
+}
+
 // Opens the stream.  Reports an error if it can't.
 bool GeneratedFile::start(const string& directory, const string& name) {
     const string path = directory + "/" + name;
diff --git a/api/Utilities.h b/api/Utilities.h
index 04169dc..cd0db72 100644
--- a/api/Utilities.h
+++ b/api/Utilities.h
@@ -47,6 +47,13 @@
  */
 double maxDoubleForInteger(int numberOfIntegerBits, int mantissaSize);
 
+/* Creates an " __attribute__((...))" tag.  If userAttribute starts with '=', we don't
+ * use the additionalAttribute.  An empty string will be returned if there are no attributes.
+ */
+std::string makeAttributeTag(const std::string& userAttribute,
+                             const std::string& additionalAttribute, int deprecatedApiLevel,
+                             const std::string& deprecatedMessage);
+
 /* This class is used to generate one source file.  There will be one instance
  * for each generated file.
  */
diff --git a/api/rs_graphics.spec b/api/rs_graphics.spec
index a932a53..af41a28 100644
--- a/api/rs_graphics.spec
+++ b/api/rs_graphics.spec
@@ -42,7 +42,7 @@
 value: RS_BLEND_SRC_ONE_MINUS_DST_ALPHA = 7
 value: RS_BLEND_SRC_SRC_ALPHA_SATURATE = 8
 value: RS_BLEND_SRC_INVALID = 100
-deprecated:
+deprecated: 22
 summary: Blend source function
 description:
 end:
@@ -60,7 +60,7 @@
 value: RS_BLEND_DST_DST_ALPHA = 6
 value: RS_BLEND_DST_ONE_MINUS_DST_ALPHA = 7
 value: RS_BLEND_DST_INVALID = 100
-deprecated:
+deprecated: 22
 summary: Blend destination function
 description:
 end:
@@ -73,7 +73,7 @@
 value: RS_CULL_FRONT = 1
 value: RS_CULL_NONE = 2
 value: RS_CULL_INVALID = 100
-deprecated:
+deprecated: 22
 summary: Culling mode
 description:
 end:
@@ -90,7 +90,7 @@
 value: RS_DEPTH_FUNC_EQUAL = 5, "Drawn if the incoming depth value is equal to that in the depth buffer"
 value: RS_DEPTH_FUNC_NOTEQUAL = 6, "Drawn if the incoming depth value is not equal to that in the depth buffer"
 value: RS_DEPTH_FUNC_INVALID = 100, "Invalid depth function"
-deprecated:
+deprecated: 22
 summary: Depth function
 description:
  Specifies conditional drawing depending on the comparison of the incoming
@@ -108,7 +108,7 @@
 value: RS_PRIMITIVE_TRIANGLE_STRIP = 4, "Vertices will be rendered as a connected triangle strip defined by the first three vertices with each additional triangle defined by a new vertex"
 value: RS_PRIMITIVE_TRIANGLE_FAN = 5, "Vertices will be rendered as a sequence of triangles that all share first vertex as the origin"
 value: RS_PRIMITIVE_INVALID = 100, "Invalid primitive"
-deprecated:
+deprecated: 22
 summary: How to intepret mesh vertex data
 description:
  Describes the way mesh vertex data is interpreted when rendering
@@ -118,7 +118,7 @@
 version: 9 22
 size: 32
 simple: _RS_HANDLE
-deprecated:
+deprecated: 22
 summary: Handle to a Font
 description:
  Opaque handle to a RenderScript font object.
@@ -130,7 +130,7 @@
 version: 9 22
 size: 32
 simple: _RS_HANDLE
-deprecated:
+deprecated: 22
 summary: Handle to a Mesh
 description:
  Opaque handle to a RenderScript mesh object.
@@ -141,7 +141,7 @@
 version: 9 22
 size: 32
 simple: _RS_HANDLE
-deprecated:
+deprecated: 22
 summary: Handle to a ProgramFragment
 description:
  Opaque handle to a RenderScript ProgramFragment object.
@@ -152,7 +152,7 @@
 version: 9 22
 size: 32
 simple: _RS_HANDLE
-deprecated:
+deprecated: 22
 summary: Handle to a ProgramVertex
 description:
  Opaque handle to a RenderScript ProgramVertex object.
@@ -163,7 +163,7 @@
 version: 9 22
 size: 32
 simple: _RS_HANDLE
-deprecated:
+deprecated: 22
 summary: Handle to a ProgramRaster
 description:
  Opaque handle to a RenderScript ProgramRaster object.
@@ -174,7 +174,7 @@
 version: 9 22
 size: 32
 simple: _RS_HANDLE
-deprecated:
+deprecated: 22
 summary: Handle to a ProgramStore
 description:
  Opaque handle to a RenderScript ProgramStore object.
@@ -214,7 +214,7 @@
 size: 32
 ret: void
 arg: rs_allocation alloc
-deprecated:
+deprecated: 22
 summary: Sync the contents of an allocation
 description:
  Sync the contents of an allocation.
@@ -241,7 +241,7 @@
 ret: void
 arg: rs_allocation colorTarget
 arg: uint slot
-deprecated:
+deprecated: 22
 summary: Set the color target
 description:
  Set the color target used for all subsequent rendering calls
@@ -255,7 +255,7 @@
 arg: rs_program_fragment ps, "program fragment object"
 arg: uint slot, "index of the constant buffer on the program"
 arg: rs_allocation c, "constants to bind"
-deprecated:
+deprecated: 22
 summary: Bind a constant allocation
 description:
  Bind a new Allocation object to a ProgramFragment or ProgramVertex.
@@ -278,7 +278,7 @@
 size: 32
 ret: void
 arg: rs_allocation depthTarget
-deprecated:
+deprecated: 22
 summary: Set the depth target
 description:
  Set the depth target used for all subsequent rendering calls
@@ -290,7 +290,7 @@
 size: 32
 ret: void
 arg: rs_font font, "object to bind"
-deprecated:
+deprecated: 22
 summary: Bind a font object
 description:
  Binds the font object to be used for all subsequent font rendering calls
@@ -302,7 +302,7 @@
 size: 32
 ret: void
 arg: rs_program_fragment pf
-deprecated:
+deprecated: 22
 summary: Bind a ProgramFragment
 description:
  Bind a new ProgramFragment to the rendering context.
@@ -314,7 +314,7 @@
 size: 32
 ret: void
 arg: rs_program_raster pr
-deprecated:
+deprecated: 22
 summary: Bind a ProgramRaster
 description:
  Bind a new ProgramRaster to the rendering context.
@@ -326,7 +326,7 @@
 size: 32
 ret: void
 arg: rs_program_store ps
-deprecated:
+deprecated: 22
 summary: Bind a ProgramStore
 description:
  Bind a new ProgramStore to the rendering context.
@@ -338,7 +338,7 @@
 size: 32
 ret: void
 arg: rs_program_vertex pv
-deprecated:
+deprecated: 22
 summary: Bind a ProgramVertex
 description:
  Bind a new ProgramVertex to the rendering context.
@@ -352,7 +352,7 @@
 arg: rs_program_fragment fragment
 arg: uint slot
 arg: rs_sampler sampler
-deprecated:
+deprecated: 22
 summary: Bind a sampler
 description:
  Bind a new Sampler object to a ProgramFragment.  The sampler will
@@ -367,7 +367,7 @@
 arg: rs_program_fragment v
 arg: uint slot
 arg: rs_allocation alloc
-deprecated:
+deprecated: 22
 summary: Bind a texture allocation
 description:
  Bind a new Allocation object to a ProgramFragment.  The
@@ -381,7 +381,7 @@
 version: 14 22
 size: 32
 ret: void
-deprecated:
+deprecated: 22
 summary: Clear all color and depth targets
 description:
  Clear all color and depth targets and resume rendering into
@@ -397,7 +397,7 @@
 arg: float g
 arg: float b
 arg: float a
-deprecated:
+deprecated: 22
 summary: Clear the specified color from the surface
 description:
  Clears the rendering surface to the specified color.
@@ -409,7 +409,7 @@
 size: 32
 ret: void
 arg: uint slot
-deprecated:
+deprecated: 22
 summary: Clear the color target
 description:
  Clear the previously set color target
@@ -421,7 +421,7 @@
 size: 32
 ret: void
 arg: float value
-deprecated:
+deprecated: 22
 summary: Clear the depth surface
 description:
  Clears the depth suface to the specified value.
@@ -432,7 +432,7 @@
 version: 14 22
 size: 32
 ret: void
-deprecated:
+deprecated: 22
 summary: Clear the depth target
 description:
  Clear the previously set depth target
@@ -444,7 +444,7 @@
 size: 32
 ret: void
 arg: rs_mesh ism, "mesh object to render"
-deprecated:
+deprecated: 22
 summary: Draw a mesh
 description:
  Draw a mesh using the current context state.
@@ -493,7 +493,7 @@
 arg: float x4
 arg: float y4
 arg: float z4
-deprecated:
+deprecated: 22
 summary: Draw a quad
 description:
  Low performance utility function for drawing a simple quad.  Not intended for
@@ -525,7 +525,7 @@
 arg: float z4
 arg: float u4
 arg: float v4
-deprecated:
+deprecated: 22
 summary: Draw a textured quad
 description:
  Low performance utility function for drawing a textured quad.  Not intended
@@ -542,7 +542,7 @@
 arg: float x2
 arg: float y2
 arg: float z
-deprecated:
+deprecated: 22
 summary: Draw a rectangle
 description:
  Low performance utility function for drawing a simple rectangle.  Not
@@ -559,7 +559,7 @@
 arg: float z
 arg: float w
 arg: float h
-deprecated:
+deprecated: 22
 summary: Draw rectangles in screenspace
 description:
  Low performance function for drawing rectangles in screenspace.  This
@@ -576,7 +576,7 @@
 arg: const char* text
 arg: int x
 arg: int y
-deprecated:
+deprecated: 22
 summary: Draw a text string
 description:
  Draws text given a string and location
@@ -597,7 +597,7 @@
 version: 14 22
 size: 32
 ret: uint
-deprecated:
+deprecated: 22
 summary: End rendering commands
 description:
  Force RenderScript to finish all rendering commands
@@ -612,7 +612,7 @@
 arg: float g, "green component"
 arg: float b, "blue component"
 arg: float a, "alpha component"
-deprecated:
+deprecated: 22
 summary: Set the font color
 description:
  Sets the font color for all subsequent rendering calls
@@ -623,7 +623,7 @@
 version: 9 22
 size: 32
 ret: uint
-deprecated:
+deprecated: 22
 summary: Get the surface height
 description:
  Get the height of the current rendering surface.
@@ -634,7 +634,7 @@
 version: 9 22
 size: 32
 ret: uint
-deprecated:
+deprecated: 22
 summary: Get the surface width
 description:
  Get the width of the current rendering surface.
@@ -650,7 +650,7 @@
 arg: int* right
 arg: int* top
 arg: int* bottom
-deprecated:
+deprecated: 22
 summary: Get the bounding box for a text string
 description:
  Returns the bounding box of the text relative to (0, 0)
@@ -681,7 +681,7 @@
 arg: float* maxX
 arg: float* maxY
 arg: float* maxZ
-deprecated:
+deprecated: 22
 summary: Compute a bounding box
 description:
  Computes an axis aligned bounding box of a mesh object
@@ -714,7 +714,7 @@
 ret: rs_allocation, "allocation containing index data"
 arg: rs_mesh m, "mesh to get data from"
 arg: uint32_t index, "index of the index allocation"
-deprecated:
+deprecated: 22
 summary: Return an allocation containing index data
 description:
  Returns an allocation containing index data or a null
@@ -728,7 +728,7 @@
 ret: rs_primitive, "primitive describing how the mesh is rendered"
 arg: rs_mesh m, "mesh to get data from"
 arg: uint32_t index, "index of the primitive"
-deprecated:
+deprecated: 22
 summary: Return the primitive
 description:
  Returns the primitive describing how a part of the mesh is
@@ -741,7 +741,7 @@
 size: 32
 ret: uint32_t, "number of primitive groups in the mesh. This would include simple primitives as well as allocations containing index data"
 arg: rs_mesh m, "mesh to get data from"
-deprecated:
+deprecated: 22
 summary: Return the number of index sets
 description:
  Meshes could have multiple index sets, this function returns
@@ -755,7 +755,7 @@
 ret: rs_allocation, "allocation containing vertex data"
 arg: rs_mesh m, "mesh to get data from"
 arg: uint32_t index, "index of the vertex allocation"
-deprecated:
+deprecated: 22
 summary: Return a vertex allocation
 description:
  Returns an allocation that is part of the mesh and contains
@@ -768,7 +768,7 @@
 size: 32
 ret: uint32_t, "number of allocations in the mesh that contain vertex data"
 arg: rs_mesh m, "mesh to get data from"
-deprecated:
+deprecated: 22
 summary: Return the number of vertex allocations
 description:
  Returns the number of allocations in the mesh that contain
@@ -785,7 +785,7 @@
 arg: float g
 arg: float b
 arg: float a
-deprecated:
+deprecated: 22
 summary: Set the constant color for a fixed function emulation program
 description:
  Set the constant color for a fixed function emulation program.
@@ -797,7 +797,7 @@
 size: 32
 ret: void
 arg: rs_matrix4x4* proj, "matrix to store the current projection matrix into"
-deprecated:
+deprecated: 22
 summary: Get the projection matrix for a fixed function vertex program
 description:
  Get the projection matrix for a currently bound fixed function
@@ -811,7 +811,7 @@
 size: 32
 ret: void
 arg: const rs_matrix4x4* model, "model matrix"
-deprecated:
+deprecated: 22
 summary: Load the model matrix for a bound fixed function vertex program
 description:
  Load the model matrix for a currently bound fixed function
@@ -825,7 +825,7 @@
 size: 32
 ret: void
 arg: const rs_matrix4x4* proj, "projection matrix"
-deprecated:
+deprecated: 22
 summary: Load the projection matrix for a bound fixed function vertex program
 description:
  Load the projection matrix for a currently bound fixed function
@@ -839,7 +839,7 @@
 size: 32
 ret: void
 arg: const rs_matrix4x4* tex, "texture matrix"
-deprecated:
+deprecated: 22
 summary:  Load the texture matrix for a bound fixed function vertex program
 description:
  Load the texture matrix for a currently bound fixed function
@@ -853,7 +853,7 @@
 size: 32
 ret: rs_cull_mode
 arg: rs_program_raster pr, "program raster to query"
-deprecated:
+deprecated: 22
 summary: Get program raster cull mode
 description:
  Get program raster cull mode
@@ -865,7 +865,7 @@
 size: 32
 ret: bool
 arg: rs_program_raster pr, "program raster to query"
-deprecated:
+deprecated: 22
 summary: Get program raster point sprite state
 description:
  Get program raster point sprite state
@@ -877,7 +877,7 @@
 size: 32
 ret: rs_blend_dst_func
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store blend destination function
 description:
  Get program store blend destination function
@@ -889,7 +889,7 @@
 size: 32
 ret: rs_blend_src_func
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store blend source function
 description:
  Get program store blend source function
@@ -901,7 +901,7 @@
 size: 32
 ret: rs_depth_func
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store depth function
 description:
  Get program store depth function
@@ -913,7 +913,7 @@
 size: 32
 ret: bool
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store alpha component color mask
 description:
  Get program store alpha component color mask
@@ -925,7 +925,7 @@
 size: 32
 ret: bool
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store blur component color mask
 description:
  Get program store blur component color mask
@@ -937,7 +937,7 @@
 size: 32
 ret: bool
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store green component color mask
 description:
  Get program store green component color mask
@@ -949,7 +949,7 @@
 size: 32
 ret: bool
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store red component color mask
 description:
  Get program store red component color mask
@@ -961,7 +961,7 @@
 size: 32
 ret: bool
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store depth mask
 description:
  Get program store depth mask
@@ -973,7 +973,7 @@
 size: 32
 ret: bool
 arg: rs_program_store ps, "program store to query"
-deprecated:
+deprecated: 22
 summary: Get program store dither state
 description:
  Get program store dither state
diff --git a/api/rs_math.spec b/api/rs_math.spec
index cdd7123..6e7daf6 100644
--- a/api/rs_math.spec
+++ b/api/rs_math.spec
@@ -65,7 +65,7 @@
 constant: M_2_PIl
 value: 0.636619772367581343075535053490057448f
 hidden:
-deprecated: Use M_2_PI instead.
+deprecated: 22, Use M_2_PI instead.
 summary: 2 / pi, as a 32 bit float
 description:
  2 divided by pi, as a 32 bit float.
@@ -2179,7 +2179,7 @@
 arg: #1 amount, "Value to clamp."
 arg: #1 low, "Lower bound."
 arg: #1 high, "Upper bound."
-deprecated: Use @clamp() instead.
+deprecated: 22, Use @clamp() instead.
 summary: Restrain a value to a range
 description:
  Clamp a value between low and high.
@@ -2190,7 +2190,7 @@
 attrib: const
 ret: float
 arg: float v
-deprecated: Use @fract() instead.
+deprecated: 22, Use @fract() instead.
 summary: Returns the fractional part of a float
 description:
  Returns the fractional part of a float
diff --git a/api/rs_object_info.spec b/api/rs_object_info.spec
index cf9b56b..6a6336d 100644
--- a/api/rs_object_info.spec
+++ b/api/rs_object_info.spec
@@ -299,7 +299,7 @@
 function: rsGetAllocation
 ret: rs_allocation
 arg: const void* p
-deprecated: This function is deprecated and will be removed from the SDK in a future release.
+deprecated: 22, This function is deprecated and will be removed from the SDK in a future release.
 summary: Return the Allocation for a given pointer
 description:
  Returns the Allocation for a given pointer.  The pointer should point within a valid
diff --git a/api/rs_value_types.spec b/api/rs_value_types.spec
index a4f303a..ecd3f2f 100644
--- a/api/rs_value_types.spec
+++ b/api/rs_value_types.spec
@@ -209,7 +209,8 @@
 end:
 
 type: float2
-simple: float __attribute__((ext_vector_type(2)))
+simple: float
+attrib: ext_vector_type(2)
 summary: Two 32 bit floats
 description:
  A vector of two floats.  These two floats are packed into a single 64 bit field
@@ -220,7 +221,8 @@
 end:
 
 type: float3
-simple: float __attribute__((ext_vector_type(3)))
+simple: float
+attrib: ext_vector_type(3)
 summary: Three 32 bit floats
 description:
  A vector of three floats.  These three floats are packed into a single 128 bit field
@@ -228,7 +230,8 @@
 end:
 
 type: float4
-simple: float __attribute__((ext_vector_type(4)))
+simple: float
+attrib: ext_vector_type(4)
 summary: Four 32 bit floats
 description:
  A vector of four floats type.  These four floats are packed into a single 128 bit field
@@ -237,7 +240,8 @@
 
 
 type: double2
-simple: double __attribute__((ext_vector_type(2)))
+simple: double
+attrib: ext_vector_type(2)
 summary: Two 64 bit floats
 description:
  A vector of two doubles.  These two double fields packed into a single 128 bit field
@@ -245,7 +249,8 @@
 end:
 
 type: double3
-simple: double __attribute__((ext_vector_type(3)))
+simple: double
+attrib: ext_vector_type(3)
 summary: Three 64 bit floats
 description:
  A vector of three doubles.  These three double fields packed into a single 256 bit field
@@ -253,7 +258,8 @@
 end:
 
 type: double4
-simple: double __attribute__((ext_vector_type(4)))
+simple: double
+attrib: ext_vector_type(4)
 summary: Four 64 bit floats
 description:
  A vector of four doubles.  These four double fields packed into a single 256 bit field
@@ -262,7 +268,8 @@
 
 
 type: uchar2
-simple: uchar __attribute__((ext_vector_type(2)))
+simple: uchar
+attrib: ext_vector_type(2)
 summary: Two 8 bit unsigned integers
 description:
  A vector of two uchars.  These two uchar fields packed into a single 16 bit field
@@ -270,7 +277,8 @@
 end:
 
 type: uchar3
-simple: uchar __attribute__((ext_vector_type(3)))
+simple: uchar
+attrib: ext_vector_type(3)
 summary: Three 8 bit unsigned integers
 description:
  A vector of three uchars.  These three uchar fields packed into a single 32 bit field
@@ -278,7 +286,8 @@
 end:
 
 type: uchar4
-simple: uchar __attribute__((ext_vector_type(4)))
+simple: uchar
+attrib: ext_vector_type(4)
 summary: Four 8 bit unsigned integers
 description:
  A vector of four uchars.  These four uchar fields packed into a single 32 bit field
@@ -287,7 +296,8 @@
 
 
 type: ushort2
-simple: ushort __attribute__((ext_vector_type(2)))
+simple: ushort
+attrib: ext_vector_type(2)
 summary: Two 16 bit unsigned integers
 description:
  A vector of two ushorts.  These two ushort fields packed into a single 32 bit field
@@ -295,7 +305,8 @@
 end:
 
 type: ushort3
-simple: ushort __attribute__((ext_vector_type(3)))
+simple: ushort
+attrib: ext_vector_type(3)
 summary: Three 16 bit unsigned integers
 description:
  A vector of three ushorts.  These three ushort fields packed into a single 64 bit field
@@ -303,7 +314,8 @@
 end:
 
 type: ushort4
-simple: ushort __attribute__((ext_vector_type(4)))
+simple: ushort
+attrib: ext_vector_type(4)
 summary: Four 16 bit unsigned integers
 description:
  A vector of four ushorts.  These four ushort fields packed into a single 64 bit field
@@ -312,7 +324,8 @@
 
 
 type: uint2
-simple: uint __attribute__((ext_vector_type(2)))
+simple: uint
+attrib: ext_vector_type(2)
 summary: Two 32 bit unsigned integers
 description:
  A vector of two uints.  These two uints are packed into a single 64 bit field
@@ -320,7 +333,8 @@
 end:
 
 type: uint3
-simple: uint __attribute__((ext_vector_type(3)))
+simple: uint
+attrib: ext_vector_type(3)
 summary: Three 32 bit unsigned integers
 description:
  A vector of three uints.  These three uints are packed into a single 128 bit field
@@ -328,7 +342,8 @@
 end:
 
 type: uint4
-simple: uint __attribute__((ext_vector_type(4)))
+simple: uint
+attrib: ext_vector_type(4)
 summary: Four 32 bit unsigned integers
 description:
  A vector of four uints.  These four uints are packed into a single 128 bit field
@@ -337,7 +352,8 @@
 
 
 type: ulong2
-simple: ulong __attribute__((ext_vector_type(2)))
+simple: ulong
+attrib: ext_vector_type(2)
 summary: Two 64 bit unsigned integers
 description:
  A vector of two ulongs.  These two ulongs are packed into a single 128 bit field
@@ -345,7 +361,8 @@
 end:
 
 type: ulong3
-simple: ulong __attribute__((ext_vector_type(3)))
+simple: ulong
+attrib: ext_vector_type(3)
 summary: Three 64 bit unsigned integers
 description:
  A vector of three ulongs.  These three ulong fields packed into a single 256 bit field
@@ -353,7 +370,8 @@
 end:
 
 type: ulong4
-simple: ulong __attribute__((ext_vector_type(4)))
+simple: ulong
+attrib: ext_vector_type(4)
 summary: Four 64 bit unsigned integers
 description:
  A vector of four ulongs.  These four ulong fields packed into a single 256 bit field
@@ -362,7 +380,8 @@
 
 
 type: char2
-simple: char __attribute__((ext_vector_type(2)))
+simple: char
+attrib: ext_vector_type(2)
 summary: Two 8 bit signed integers
 description:
  A vector of two chars.  These two chars are packed into a single 16 bit field
@@ -370,7 +389,8 @@
 end:
 
 type: char3
-simple: char __attribute__((ext_vector_type(3)))
+simple: char
+attrib: ext_vector_type(3)
 summary: Three 8 bit signed integers
 description:
  A vector of three chars.  These three chars are packed into a single 32 bit field
@@ -378,7 +398,8 @@
 end:
 
 type: char4
-simple: char __attribute__((ext_vector_type(4)))
+simple: char
+attrib: ext_vector_type(4)
 summary: Four 8 bit signed integers
 description:
  A vector of four chars.  These four chars are packed into a single 32 bit field
@@ -387,7 +408,8 @@
 
 
 type: short2
-simple: short __attribute__((ext_vector_type(2)))
+simple: short
+attrib: ext_vector_type(2)
 summary: Two 16 bit signed integers
 description:
  A vector of two shorts.  These two shorts are packed into a single 32 bit field
@@ -395,7 +417,8 @@
 end:
 
 type: short3
-simple: short __attribute__((ext_vector_type(3)))
+simple: short
+attrib: ext_vector_type(3)
 summary: Three 16 bit signed integers
 description:
  A vector of three shorts.  These three short fields packed into a single 64 bit field
@@ -403,7 +426,8 @@
 end:
 
 type: short4
-simple: short __attribute__((ext_vector_type(4)))
+simple: short
+attrib: ext_vector_type(4)
 summary: Four 16 bit signed integers
 description:
  A vector of four shorts.  These four short fields packed into a single 64 bit field
@@ -412,7 +436,8 @@
 
 
 type: int2
-simple: int __attribute__((ext_vector_type(2)))
+simple: int
+attrib: ext_vector_type(2)
 summary: Two 32 bit signed integers
 description:
  A vector of two ints.  These two ints are packed into a single 64 bit field
@@ -420,7 +445,8 @@
 end:
 
 type: int3
-simple: int __attribute__((ext_vector_type(3)))
+simple: int
+attrib: ext_vector_type(3)
 summary: Three 32 bit signed integers
 description:
  A vector of three ints.  These three ints are packed into a single 128 bit field
@@ -428,7 +454,8 @@
 end:
 
 type: int4
-simple: int __attribute__((ext_vector_type(4)))
+simple: int
+attrib: ext_vector_type(4)
 summary: Four 32 bit signed integers
 description:
  A vector of four ints.  These two fours are packed into a single 128 bit field
@@ -437,7 +464,8 @@
 
 
 type: long2
-simple: long __attribute__((ext_vector_type(2)))
+simple: long
+attrib: ext_vector_type(2)
 summary: Two 64 bit signed integers
 description:
  A vector of two longs.  These two longs are packed into a single 128 bit field
@@ -445,7 +473,8 @@
 end:
 
 type: long3
-simple: long __attribute__((ext_vector_type(3)))
+simple: long
+attrib: ext_vector_type(3)
 summary: Three 64 bit signed integers
 description:
  A vector of three longs.  These three longs are packed into a single 256 bit field
@@ -453,7 +482,8 @@
 end:
 
 type: long4
-simple: long __attribute__((ext_vector_type(4)))
+simple: long
+attrib: ext_vector_type(4)
 summary: Four 64 bit signed integers
 description:
  A vector of four longs.  These four longs are packed into a single 256 bit field