Home | History | Annotate | Download | only in api
      1 /*
      2  * Copyright (C) 2015 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ANDROID_RS_API_GENERATOR_SPECIFICATION_H
     18 #define ANDROID_RS_API_GENERATOR_SPECIFICATION_H
     19 
     20 // See Generator.cpp for documentation of the .spec file format.
     21 
     22 #include <climits>
     23 #include <fstream>
     24 #include <list>
     25 #include <map>
     26 #include <string>
     27 #include <vector>
     28 
     29 class Constant;
     30 class ConstantSpecification;
     31 class Function;
     32 class FunctionPermutation;
     33 class FunctionSpecification;
     34 class SpecFile;
     35 class Specification;
     36 class Scanner;
     37 class SystemSpecification;
     38 class Type;
     39 class TypeSpecification;
     40 
     41 enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT };
     42 
     43 // Table of type equivalences.
     44 struct NumericalType {
     45     const char* specType;    // Name found in the .spec file
     46     const char* rsDataType;  // RS data type
     47     const char* cType;       // Type in a C file
     48     const char* javaType;    // Type in a Java file
     49     NumberKind kind;
     50     /* For integers, number of bits of the number, excluding the sign bit.
     51      * For floats, number of implied bits of the mantissa.
     52      */
     53     int significantBits;
     54     // For floats, number of bits of the exponent.  0 for integer types.
     55     int exponentBits;
     56 };
     57 
     58 /* Corresponds to one parameter line in a .spec file.  These will be parsed when
     59  * we instantiate the FunctionPermutation(s) that correspond to one FunctionSpecification.
     60  */
     61 struct ParameterEntry {
     62     std::string type;
     63     std::string name;
     64     /* Optional information on how to generate test values for this parameter.  Can be:
     65      * - range(low, high): Generates values between these two limits only.
     66      * - above(other_parameter): The values must be greater than those of the named parameter.
     67      *       Used for clamp.
     68      * - compatible(type): The values must also be fully representable in the specified type.
     69      * - conditional: Don't verify this value the function return NaN.
     70      */
     71     std::string testOption;
     72     std::string documentation;
     73     int lineNumber;
     74 };
     75 
     76 /* Information about a parameter to a function.  The values of all the fields should only be set by
     77  * parseParameterDefinition.
     78  */
     79 struct ParameterDefinition {
     80     std::string rsType;        // The Renderscript type, e.g. "uint3"
     81     std::string rsBaseType;    // As above but without the number, e.g. "uint"
     82     std::string javaBaseType;  // The type we need to declare in Java, e.g. "unsigned int"
     83     std::string specType;      // The type found in the spec, e.g. "f16"
     84     bool isFloatType;          // True if it's a floating point value
     85     /* The number of entries in the vector.  It should be either "1", "2", "3", or "4".  It's also
     86      * "1" for scalars.
     87      */
     88     std::string mVectorSize;
     89     /* The space the vector takes in an array.  It's the same as the vector size, except for size
     90      * "3", where the width is "4".
     91      */
     92     std::string vectorWidth;
     93 
     94     std::string specName;       // e.g. x, as found in the spec file
     95     std::string variableName;   // e.g. inX, used both in .rs and .java
     96     std::string rsAllocName;    // e.g. gAllocInX
     97     std::string javaAllocName;  // e.g. inX
     98     std::string javaArrayName;  // e.g. arrayInX
     99     std::string doubleVariableName; // e.g. inXDouble, used in .java for storing Float16 parameters
    100                                     // in double.
    101 
    102     // If non empty, the mininum and maximum values to be used when generating the test data.
    103     std::string minValue;
    104     std::string maxValue;
    105     /* If non empty, contains the name of another parameter that should be smaller or equal to this
    106      * parameter, i.e.  value(smallerParameter) <= value(this).  This is used when testing clamp.
    107      */
    108     std::string smallerParameter;
    109 
    110     bool isOutParameter;       // True if this parameter returns data from the script.
    111     bool undefinedIfOutIsNan;  // If true, we don't validate if 'out' is NaN.
    112 
    113     int typeIndex;            // Index in the TYPES array. Negative if not found in the array.
    114     int compatibleTypeIndex;  // Index in TYPES for which the test data must also fit.
    115 
    116     /* Fill this object from the type, name, and testOption.
    117      * isReturn is true if we're processing the "return:"
    118      */
    119     void parseParameterDefinition(const std::string& type, const std::string& name,
    120                                   const std::string& testOption, int lineNumber, bool isReturn,
    121                                   Scanner* scanner);
    122 
    123     bool isFloat16Parameter() const { return specType.compare("f16") == 0; }
    124 };
    125 
    126 struct VersionInfo {
    127     /* The range of versions a specification applies to. Zero if there's no restriction,
    128      * so an API that became available at 12 and is still valid would have min:12 max:0.
    129      * If non zero, both versions should be at least 9, the API level that introduced
    130      * RenderScript.
    131      */
    132     unsigned int minVersion;
    133     unsigned int maxVersion;
    134     // Either 0, 32 or 64.  If 0, this definition is valid for both 32 and 64 bits.
    135     int intSize;
    136 
    137     VersionInfo() : minVersion(0), maxVersion(0), intSize(0) {}
    138     /* Scan the version info from the spec file.  maxApiLevel specifies the maximum level
    139      * we are interested in.  This may alter maxVersion.  This method returns false if the
    140      * minVersion is greater than the maxApiLevel.
    141      */
    142     bool scan(Scanner* scanner, unsigned int maxApiLevel);
    143     /* Return true if the target can be found whitin the range. */
    144     bool includesVersion(int target) const {
    145         return (minVersion == 0 || target >= minVersion) &&
    146                (maxVersion == 0 || target <= maxVersion);
    147     }
    148 
    149     static constexpr unsigned int kUnreleasedVersion = UINT_MAX;
    150 };
    151 
    152 // We have three type of definitions
    153 class Definition {
    154 protected:
    155     std::string mName;
    156     /* If greater than 0, this definition is deprecated.  It's the API level at which
    157      * we added the deprecation warning.
    158      */
    159     int mDeprecatedApiLevel;
    160     std::string mDeprecatedMessage;         // Optional specific warning if the API is deprecated
    161     bool mHidden;                           // True if it should not be documented
    162     std::string mSummary;                   // A one-line description
    163     std::vector<std::string> mDescription;  // The comments to be included in the header
    164     std::string mUrl;                       // The URL of the detailed documentation
    165     int mFinalVersion;  // API level at which this API was removed, 0 if API is still valid
    166 
    167 public:
    168     Definition(const std::string& name);
    169 
    170     std::string getName() const { return mName; }
    171     bool deprecated() const { return mDeprecatedApiLevel > 0; }
    172     int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; }
    173     std::string getDeprecatedMessage() const { return mDeprecatedMessage; }
    174     bool hidden() const { return mHidden; }
    175     std::string getSummary() const { return mSummary; }
    176     const std::vector<std::string>& getDescription() const { return mDescription; }
    177     std::string getUrl() const { return mUrl; }
    178     int getFinalVersion() const { return mFinalVersion; }
    179 
    180     void scanDocumentationTags(Scanner* scanner, bool firstOccurence, const SpecFile* specFile);
    181     // Keep track of the final version of this API, if any.
    182     void updateFinalVersion(const VersionInfo& info);
    183 };
    184 
    185 /* Represents a constant, like M_PI.  This is a grouping of the version specific specifications.
    186  * We'll only have one instance of Constant for each name.
    187  */
    188 class Constant : public Definition {
    189 private:
    190     std::vector<ConstantSpecification*> mSpecifications;  // Owned
    191 
    192 public:
    193     Constant(const std::string& name) : Definition(name) {}
    194     ~Constant();
    195 
    196     const std::vector<ConstantSpecification*> getSpecifications() const { return mSpecifications; }
    197     // This method should only be called by the scanning code.
    198     void addSpecification(ConstantSpecification* spec) { mSpecifications.push_back(spec); }
    199 };
    200 
    201 /* Represents a type, like "float4".  This is a grouping of the version specific specifications.
    202  * We'll only have one instance of Type for each name.
    203  */
    204 class Type : public Definition {
    205 private:
    206     std::vector<TypeSpecification*> mSpecifications;  // Owned
    207 
    208 public:
    209     Type(const std::string& name) : Definition(name) {}
    210     ~Type();
    211 
    212     const std::vector<TypeSpecification*> getSpecifications() const { return mSpecifications; }
    213     // This method should only be called by the scanning code.
    214     void addSpecification(TypeSpecification* spec) { mSpecifications.push_back(spec); }
    215 };
    216 
    217 /* Represents a function, like "clamp".  Even though the spec file contains many entries for clamp,
    218  * we'll only have one clamp instance.
    219  */
    220 class Function : public Definition {
    221 private:
    222     // mName in the base class contains the lower case name, e.g. native_log
    223     std::string mCapitalizedName;  // The capitalized name, e.g. NativeLog
    224 
    225     // The unique parameters between all the specifications.  NOT OWNED.
    226     std::vector<ParameterEntry*> mParameters;
    227     std::string mReturnDocumentation;
    228 
    229     std::vector<FunctionSpecification*> mSpecifications;  // Owned
    230 
    231 public:
    232     Function(const std::string& name);
    233     ~Function();
    234 
    235     std::string getCapitalizedName() const { return mCapitalizedName; }
    236     const std::vector<ParameterEntry*>& getParameters() const { return mParameters; }
    237     std::string getReturnDocumentation() const { return mReturnDocumentation; }
    238     const std::vector<FunctionSpecification*> getSpecifications() const { return mSpecifications; }
    239 
    240     bool someParametersAreDocumented() const;
    241 
    242     // The following methods should only be called by the scanning code.
    243     void addParameter(ParameterEntry* entry, Scanner* scanner);
    244     void addReturn(ParameterEntry* entry, Scanner* scanner);
    245     void addSpecification(FunctionSpecification* spec) { mSpecifications.push_back(spec); }
    246 };
    247 
    248 /* Base class for TypeSpecification, ConstantSpecification, and FunctionSpecification.
    249  * A specification can be specific to a range of RenderScript version or 32bits vs 64 bits.
    250  * This base class contains code to parse and store this version information.
    251  */
    252 class Specification {
    253 protected:
    254     VersionInfo mVersionInfo;
    255     void scanVersionInfo(Scanner* scanner);
    256 
    257 public:
    258     VersionInfo getVersionInfo() const { return mVersionInfo; }
    259 };
    260 
    261 /* Defines one of the many variations of a constant.  There's a one to one correspondance between
    262  * ConstantSpecification objects and entries in the spec file.
    263  */
    264 class ConstantSpecification : public Specification {
    265 private:
    266     Constant* mConstant;  // Not owned
    267 
    268     std::string mValue;  // E.g. "3.1415"
    269 public:
    270     ConstantSpecification(Constant* constant) : mConstant(constant) {}
    271 
    272     Constant* getConstant() const { return mConstant; }
    273     std::string getValue() const { return mValue; }
    274 
    275     // Parse a constant specification and add it to specFile.
    276     static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
    277 };
    278 
    279 enum TypeKind {
    280     SIMPLE,
    281     RS_OBJECT,
    282     STRUCT,
    283     ENUM,
    284 };
    285 
    286 /* Defines one of the many variations of a type.  There's a one to one correspondance between
    287  * TypeSpecification objects and entries in the spec file.
    288  */
    289 class TypeSpecification : public Specification {
    290 private:
    291     Type* mType;  // Not owned
    292 
    293     TypeKind mKind;  // The kind of type specification
    294 
    295     // If mKind is SIMPLE:
    296     std::string mSimpleType;  // The definition of the type
    297 
    298     // If mKind is STRUCT:
    299     std::string mStructName;                  // The name found after the struct keyword
    300     std::vector<std::string> mFields;         // One entry per struct field
    301     std::vector<std::string> mFieldComments;  // One entry per struct field
    302     std::string mAttribute;                   // Some structures may have attributes
    303 
    304     // If mKind is ENUM:
    305     std::string mEnumName;                    // The name found after the enum keyword
    306     std::vector<std::string> mValues;         // One entry per enum value
    307     std::vector<std::string> mValueComments;  // One entry per enum value
    308 public:
    309     TypeSpecification(Type* type) : mType(type) {}
    310 
    311     Type* getType() const { return mType; }
    312     TypeKind getKind() const { return mKind; }
    313     std::string getSimpleType() const { return mSimpleType; }
    314     std::string getStructName() const { return mStructName; }
    315     const std::vector<std::string>& getFields() const { return mFields; }
    316     const std::vector<std::string>& getFieldComments() const { return mFieldComments; }
    317     std::string getAttribute() const { return mAttribute; }
    318     std::string getEnumName() const { return mEnumName; }
    319     const std::vector<std::string>& getValues() const { return mValues; }
    320     const std::vector<std::string>& getValueComments() const { return mValueComments; }
    321 
    322     // Parse a type specification and add it to specFile.
    323     static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
    324 };
    325 
    326 // Maximum number of placeholders (like #1, #2) in function specifications.
    327 const int MAX_REPLACEABLES = 4;
    328 
    329 /* Defines one of the many variations of the function.  There's a one to one correspondance between
    330  * FunctionSpecification objects and entries in the spec file.  Some of the strings that are parts
    331  * of a FunctionSpecification can include placeholders, which are "#1", "#2", "#3", and "#4".  We'll
    332  * replace these by values before generating the files.
    333  */
    334 class FunctionSpecification : public Specification {
    335 private:
    336     Function* mFunction;  // Not owned
    337 
    338     /* How to test.  One of:
    339      * "scalar": Generate test code that checks entries of each vector indepently.  E.g. for
    340      *           sin(float3), the test code will call the CoreMathVerfier.computeSin 3 times.
    341      * "limited": Like "scalar" but we don't generate extreme values.  This is not currently
    342      *            enabled as we were generating to many errors.
    343      * "custom": Like "scalar" but instead of calling CoreMathVerifier.computeXXX() to compute
    344      *           the expected value, we call instead CoreMathVerifier.verifyXXX().  This method
    345      *           returns a string that contains the error message, null if there's no error.
    346      * "vector": Generate test code that calls the CoreMathVerifier only once for each vector.
    347      *           This is useful for APIs like dot() or length().
    348      * "noverify": Generate test code that calls the API but don't verify the returned value.
    349      *             This can discover unresolved references.
    350      * "": Don't test.  This is the default.
    351      */
    352     std::string mTest;
    353     bool mInternal;               // Internal. Not visible to users. (Default: false)
    354     bool mIntrinsic;              // Compiler intrinsic that is lowered to an internal API.
    355                                   // (Default: false)
    356     std::string mAttribute;       // Function attributes.
    357     std::string mPrecisionLimit;  // Maximum precision required when checking output of this
    358                                   // function.
    359 
    360     // The vectors of values with which we'll replace #1, #2, ...
    361     std::vector<std::vector<std::string> > mReplaceables;
    362 
    363     // i-th entry is true if each entry in mReplaceables[i] has an equivalent
    364     // RS numerical type (i.e. present in TYPES global)
    365     std::vector<bool> mIsRSTAllowed;
    366 
    367     /* The collection of permutations for this specification, i.e. this class instantianted
    368      * for specific values of #1, #2, etc.  Owned.
    369      */
    370     std::vector<FunctionPermutation*> mPermutations;
    371 
    372     // The following fields may contain placeholders that will be replaced using the mReplaceables.
    373 
    374     /* As of this writing, convert_... is the only function with #1 in its name.
    375      * The related Function object contains the name of the function without #n, e.g. convert.
    376      * This is the name with the #, e.g. convert_#1_#2
    377      */
    378     std::string mUnexpandedName;
    379     ParameterEntry* mReturn;                   // The return type. The name should be empty.  Owned.
    380     std::vector<ParameterEntry*> mParameters;  // The parameters.  Owned.
    381     std::vector<std::string> mInline;          // The inline code to be included in the header
    382 
    383     /* Substitute the placeholders in the strings (e.g. #1, #2, ...) by the
    384      * corresponding entries in mReplaceables.  Substitute placeholders for RS
    385      * types (#RST_1, #RST_2, ...) by the RS Data type strings (UNSIGNED_8,
    386      * FLOAT_32 etc.) of the corresponding types in mReplaceables.
    387      * indexOfReplaceable1 selects with value to use for #1, same for 2, 3, and
    388      * 4.
    389      */
    390     std::string expandString(std::string s, int indexOfReplaceable[MAX_REPLACEABLES]) const;
    391     void expandStringVector(const std::vector<std::string>& in,
    392                             int replacementIndexes[MAX_REPLACEABLES],
    393                             std::vector<std::string>* out) const;
    394 
    395     // Helper function used by expandString to perform #RST_* substitution
    396     std::string expandRSTypeInString(const std::string &s,
    397                                      const std::string &pattern,
    398                                      const std::string &cTypeStr) const;
    399 
    400     // Fill the mPermutations field.
    401     void createPermutations(Function* function, Scanner* scanner);
    402 
    403 public:
    404     FunctionSpecification(Function* function) : mFunction(function), mInternal(false),
    405         mIntrinsic(false), mReturn(nullptr) {}
    406     ~FunctionSpecification();
    407 
    408     Function* getFunction() const { return mFunction; }
    409     bool isInternal() const { return mInternal; }
    410     bool isIntrinsic() const { return mIntrinsic; }
    411     std::string getAttribute() const { return mAttribute; }
    412     std::string getTest() const { return mTest; }
    413     std::string getPrecisionLimit() const { return mPrecisionLimit; }
    414 
    415     const std::vector<FunctionPermutation*>& getPermutations() const { return mPermutations; }
    416 
    417     std::string getName(int replacementIndexes[MAX_REPLACEABLES]) const;
    418     void getReturn(int replacementIndexes[MAX_REPLACEABLES], std::string* retType,
    419                    int* lineNumber) const;
    420     size_t getNumberOfParams() const { return mParameters.size(); }
    421     void getParam(size_t index, int replacementIndexes[MAX_REPLACEABLES], std::string* type,
    422                   std::string* name, std::string* testOption, int* lineNumber) const;
    423     void getInlines(int replacementIndexes[MAX_REPLACEABLES],
    424                     std::vector<std::string>* inlines) const;
    425 
    426     // Parse the "test:" line.
    427     void parseTest(Scanner* scanner);
    428 
    429     // Return true if we need to generate tests for this function.
    430     bool hasTests(unsigned int versionOfTestFiles) const;
    431 
    432     bool hasInline() const { return mInline.size() > 0; }
    433 
    434     /* Return true if this function can be overloaded.  This is added by default to all
    435      * specifications, so except for the very few exceptions that start the attributes
    436      * with an '=' to avoid this, we'll return true.
    437      */
    438     bool isOverloadable() const {
    439         return mAttribute.empty() || mAttribute[0] != '=';
    440     }
    441 
    442     /* Check if RST_i is present in 's' and report an error if 'allow' is false
    443      * or the i-th replacement list is not a valid candidate for RST_i
    444      * replacement
    445      */
    446     void checkRSTPatternValidity(const std::string &s, bool allow, Scanner *scanner);
    447 
    448     // Parse a function specification and add it to specFile.
    449     static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
    450 };
    451 
    452 /* A concrete version of a function specification, where all placeholders have been replaced by
    453  * actual values.
    454  */
    455 class FunctionPermutation {
    456 private:
    457     // These are the expanded version of those found on FunctionSpecification
    458     std::string mName;
    459     std::string mNameTrunk;  // The name without any expansion, e.g. convert
    460     std::string mTest;       // How to test.  One of "scalar", "vector", "noverify", "limited", and
    461                              // "none".
    462     std::string mPrecisionLimit;  // Maximum precision required when checking output of this
    463                                   // function.
    464 
    465     // The parameters of the function.  This does not include the return type.  Owned.
    466     std::vector<ParameterDefinition*> mParams;
    467     // The return type.  nullptr if a void function.  Owned.
    468     ParameterDefinition* mReturn;
    469 
    470     // The number of input and output parameters.  mOutputCount counts the return type.
    471     int mInputCount;
    472     int mOutputCount;
    473 
    474     // Whether one of the output parameters is a float.
    475     bool mHasFloatAnswers;
    476 
    477     // The inline code that implements this function.  Will be empty if not an inline.
    478     std::vector<std::string> mInline;
    479 
    480 public:
    481     FunctionPermutation(Function* function, FunctionSpecification* specification,
    482                         int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner);
    483     ~FunctionPermutation();
    484 
    485     std::string getName() const { return mName; }
    486     std::string getNameTrunk() const { return mNameTrunk; }
    487     std::string getTest() const { return mTest; }
    488     std::string getPrecisionLimit() const { return mPrecisionLimit; }
    489 
    490     const std::vector<std::string>& getInline() const { return mInline; }
    491     const ParameterDefinition* getReturn() const { return mReturn; }
    492     int getInputCount() const { return mInputCount; }
    493     int getOutputCount() const { return mOutputCount; }
    494     bool hasFloatAnswers() const { return mHasFloatAnswers; }
    495 
    496     const std::vector<ParameterDefinition*> getParams() const { return mParams; }
    497 };
    498 
    499 // An entire spec file and the methods to process it.
    500 class SpecFile {
    501 private:
    502     std::string mSpecFileName;
    503     std::string mHeaderFileName;
    504     std::string mDetailedDocumentationUrl;
    505     std::string mBriefDescription;
    506     std::vector<std::string> mFullDescription;
    507     // Text to insert as-is in the generated header.
    508     std::vector<std::string> mVerbatimInclude;
    509 
    510     /* The constants, types, and functions specifications declared in this
    511      *  file, in the order they are found in the file.  This matters for
    512      * header generation, as some types and inline functions depend
    513      * on each other.  Pointers not owned.
    514      */
    515     std::list<ConstantSpecification*> mConstantSpecificationsList;
    516     std::list<TypeSpecification*> mTypeSpecificationsList;
    517     std::list<FunctionSpecification*> mFunctionSpecificationsList;
    518 
    519     /* The constants, types, and functions that are documented in this file.
    520      * In very rare cases, specifications for an API are split across multiple
    521      * files, e.g. currently for ClearObject().  The documentation for
    522      * that function must be found in the first spec file encountered, so the
    523      * order of the files on the command line matters.
    524      */
    525     std::map<std::string, Constant*> mDocumentedConstants;
    526     std::map<std::string, Type*> mDocumentedTypes;
    527     std::map<std::string, Function*> mDocumentedFunctions;
    528 
    529 public:
    530     explicit SpecFile(const std::string& specFileName);
    531 
    532     std::string getSpecFileName() const { return mSpecFileName; }
    533     std::string getHeaderFileName() const { return mHeaderFileName; }
    534     std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; }
    535     const std::string getBriefDescription() const { return mBriefDescription; }
    536     const std::vector<std::string>& getFullDescription() const { return mFullDescription; }
    537     const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; }
    538 
    539     const std::list<ConstantSpecification*>& getConstantSpecifications() const {
    540         return mConstantSpecificationsList;
    541     }
    542     const std::list<TypeSpecification*>& getTypeSpecifications() const {
    543         return mTypeSpecificationsList;
    544     }
    545     const std::list<FunctionSpecification*>& getFunctionSpecifications() const {
    546         return mFunctionSpecificationsList;
    547     }
    548     const std::map<std::string, Constant*>& getDocumentedConstants() const {
    549         return mDocumentedConstants;
    550     }
    551     const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; }
    552     const std::map<std::string, Function*>& getDocumentedFunctions() const {
    553         return mDocumentedFunctions;
    554     }
    555 
    556     bool hasSpecifications() const {
    557         return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() ||
    558                !mDocumentedFunctions.empty();
    559     }
    560 
    561     bool readSpecFile(unsigned int maxApiLevel);
    562 
    563     /* These are called by the parser to keep track of the specifications defined in this file.
    564      * hasDocumentation is true if this specification containes the documentation.
    565      */
    566     void addConstantSpecification(ConstantSpecification* spec, bool hasDocumentation);
    567     void addTypeSpecification(TypeSpecification* spec, bool hasDocumentation);
    568     void addFunctionSpecification(FunctionSpecification* spec, bool hasDocumentation);
    569 };
    570 
    571 // The collection of all the spec files.
    572 class SystemSpecification {
    573 private:
    574     std::vector<SpecFile*> mSpecFiles;
    575 
    576     /* Entries in the table of contents.  We accumulate them in a map to sort them.
    577      * Pointers are owned.
    578      */
    579     std::map<std::string, Constant*> mConstants;
    580     std::map<std::string, Type*> mTypes;
    581     std::map<std::string, Function*> mFunctions;
    582 
    583 public:
    584     ~SystemSpecification();
    585 
    586     /* These are called the parser to create unique instances per name.  Set *created to true
    587      * if the named specification did not already exist.
    588      */
    589     Constant* findOrCreateConstant(const std::string& name, bool* created);
    590     Type* findOrCreateType(const std::string& name, bool* created);
    591     Function* findOrCreateFunction(const std::string& name, bool* created);
    592 
    593     /* Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles.
    594      * We won't include information passed the specified level.
    595      */
    596     bool readSpecFile(const std::string& fileName, unsigned int maxApiLevel);
    597     // Generate all the files.
    598     bool generateFiles(bool forVerification, unsigned int maxApiLevel) const;
    599 
    600     const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; }
    601     const std::map<std::string, Constant*>& getConstants() const { return mConstants; }
    602     const std::map<std::string, Type*>& getTypes() const { return mTypes; }
    603     const std::map<std::string, Function*>& getFunctions() const { return mFunctions; }
    604 
    605     // Returns "<a href='...'> for the named specification, or empty if not found.
    606     std::string getHtmlAnchor(const std::string& name) const;
    607 
    608     // Returns the maximum API level specified in any spec file.
    609     unsigned int getMaximumApiLevel();
    610 };
    611 
    612 // Singleton that represents the collection of all the specs we're processing.
    613 extern SystemSpecification systemSpecification;
    614 
    615 // Table of equivalences of numerical types.
    616 extern const NumericalType TYPES[];
    617 extern const int NUM_TYPES;
    618 
    619 /* Given a renderscript type (string) calculate the vector size and base type. If the type
    620  * is not a vector the vector size is 1 and baseType is just the type itself.
    621  */
    622 void getVectorSizeAndBaseType(const std::string& type, std::string& vectorSize,
    623                               std::string& baseType);
    624 
    625 #endif  // ANDROID_RS_API_GENERATOR_SPECIFICATION_H
    626