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
29class Constant;
30class ConstantSpecification;
31class Function;
32class FunctionPermutation;
33class FunctionSpecification;
34class SpecFile;
35class Specification;
36class Scanner;
37class SystemSpecification;
38class Type;
39class TypeSpecification;
40
41enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT };
42
43// Table of type equivalences.
44struct 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 */
61struct 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 */
79struct 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
126struct 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(unsigned 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
153class Definition {
154protected:
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
167public:
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 */
188class Constant : public Definition {
189private:
190    std::vector<ConstantSpecification*> mSpecifications;  // Owned
191
192public:
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 */
204class Type : public Definition {
205private:
206    std::vector<TypeSpecification*> mSpecifications;  // Owned
207
208public:
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 */
220class Function : public Definition {
221private:
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
231public:
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 */
252class Specification {
253protected:
254    VersionInfo mVersionInfo;
255    void scanVersionInfo(Scanner* scanner);
256
257public:
258    VersionInfo getVersionInfo() const { return mVersionInfo; }
259};
260
261/* Defines one of the many variations of a constant.  There's a one to one correspondence between
262 * ConstantSpecification objects and entries in the spec file.
263 */
264class ConstantSpecification : public Specification {
265private:
266    Constant* mConstant;  // Not owned
267
268    std::string mValue;  // E.g. "3.1415"
269    std::string mType;   // E.g. "float"
270public:
271    ConstantSpecification(Constant* constant) : mConstant(constant) {}
272
273    Constant* getConstant() const { return mConstant; }
274    std::string getValue() const { return mValue; }
275    std::string getType() const { return mType; }
276
277    // Parse a constant specification and add it to specFile.
278    static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
279};
280
281enum TypeKind {
282    SIMPLE,
283    RS_OBJECT,
284    STRUCT,
285    ENUM,
286};
287
288/* Defines one of the many variations of a type.  There's a one to one correspondence between
289 * TypeSpecification objects and entries in the spec file.
290 */
291class TypeSpecification : public Specification {
292private:
293    Type* mType;  // Not owned
294
295    TypeKind mKind;  // The kind of type specification
296
297    // If mKind is SIMPLE:
298    std::string mSimpleType;  // The definition of the type
299
300    // If mKind is STRUCT:
301    std::string mStructName;                  // The name found after the struct keyword
302    std::vector<std::string> mFields;         // One entry per struct field
303    std::vector<std::string> mFieldComments;  // One entry per struct field
304    std::string mAttribute;                   // Some structures may have attributes
305
306    // If mKind is ENUM:
307    std::string mEnumName;                    // The name found after the enum keyword
308    std::vector<std::string> mValues;         // One entry per enum value
309    std::vector<std::string> mValueComments;  // One entry per enum value
310public:
311    TypeSpecification(Type* type) : mType(type) {}
312
313    Type* getType() const { return mType; }
314    TypeKind getKind() const { return mKind; }
315    std::string getSimpleType() const { return mSimpleType; }
316    std::string getStructName() const { return mStructName; }
317    const std::vector<std::string>& getFields() const { return mFields; }
318    const std::vector<std::string>& getFieldComments() const { return mFieldComments; }
319    std::string getAttribute() const { return mAttribute; }
320    std::string getEnumName() const { return mEnumName; }
321    const std::vector<std::string>& getValues() const { return mValues; }
322    const std::vector<std::string>& getValueComments() const { return mValueComments; }
323
324    // Parse a type specification and add it to specFile.
325    static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
326};
327
328// Maximum number of placeholders (like #1, #2) in function specifications.
329const int MAX_REPLACEABLES = 4;
330
331/* Defines one of the many variations of the function.  There's a one to one correspondence between
332 * FunctionSpecification objects and entries in the spec file.  Some of the strings that are parts
333 * of a FunctionSpecification can include placeholders, which are "#1", "#2", "#3", and "#4".  We'll
334 * replace these by values before generating the files.
335 */
336class FunctionSpecification : public Specification {
337private:
338    Function* mFunction;  // Not owned
339
340    /* How to test.  One of:
341     * "scalar": Generate test code that checks entries of each vector indepently.  E.g. for
342     *           sin(float3), the test code will call the CoreMathVerfier.computeSin 3 times.
343     * "limited": Like "scalar" but we don't generate extreme values.  This is not currently
344     *            enabled as we were generating to many errors.
345     * "custom": Like "scalar" but instead of calling CoreMathVerifier.computeXXX() to compute
346     *           the expected value, we call instead CoreMathVerifier.verifyXXX().  This method
347     *           returns a string that contains the error message, null if there's no error.
348     * "vector": Generate test code that calls the CoreMathVerifier only once for each vector.
349     *           This is useful for APIs like dot() or length().
350     * "noverify": Generate test code that calls the API but don't verify the returned value.
351     *             This can discover unresolved references.
352     * "": Don't test.  This is the default.
353     */
354    std::string mTest;
355    bool mInternal;               // Internal. Not visible to users. (Default: false)
356    bool mIntrinsic;              // Compiler intrinsic that is lowered to an internal API.
357                                  // (Default: false)
358    std::string mAttribute;       // Function attributes.
359    std::string mPrecisionLimit;  // Maximum precision required when checking output of this
360                                  // function.
361
362    // The vectors of values with which we'll replace #1, #2, ...
363    std::vector<std::vector<std::string> > mReplaceables;
364
365    // i-th entry is true if each entry in mReplaceables[i] has an equivalent
366    // RS numerical type (i.e. present in TYPES global)
367    std::vector<bool> mIsRSTAllowed;
368
369    /* The collection of permutations for this specification, i.e. this class instantianted
370     * for specific values of #1, #2, etc.  Owned.
371     */
372    std::vector<FunctionPermutation*> mPermutations;
373
374    // The following fields may contain placeholders that will be replaced using the mReplaceables.
375
376    /* As of this writing, convert_... is the only function with #1 in its name.
377     * The related Function object contains the name of the function without #n, e.g. convert.
378     * This is the name with the #, e.g. convert_#1_#2
379     */
380    std::string mUnexpandedName;
381    ParameterEntry* mReturn;                   // The return type. The name should be empty.  Owned.
382    std::vector<ParameterEntry*> mParameters;  // The parameters.  Owned.
383    std::vector<std::string> mInline;          // The inline code to be included in the header
384
385    /* Substitute the placeholders in the strings (e.g. #1, #2, ...) by the
386     * corresponding entries in mReplaceables.  Substitute placeholders for RS
387     * types (#RST_1, #RST_2, ...) by the RS Data type strings (UNSIGNED_8,
388     * FLOAT_32 etc.) of the corresponding types in mReplaceables.
389     * indexOfReplaceable1 selects with value to use for #1, same for 2, 3, and
390     * 4.
391     */
392    std::string expandString(std::string s, int indexOfReplaceable[MAX_REPLACEABLES]) const;
393    void expandStringVector(const std::vector<std::string>& in,
394                            int replacementIndexes[MAX_REPLACEABLES],
395                            std::vector<std::string>* out) const;
396
397    // Helper function used by expandString to perform #RST_* substitution
398    std::string expandRSTypeInString(const std::string &s,
399                                     const std::string &pattern,
400                                     const std::string &cTypeStr) const;
401
402    // Fill the mPermutations field.
403    void createPermutations(Function* function, Scanner* scanner);
404
405public:
406    FunctionSpecification(Function* function) : mFunction(function), mInternal(false),
407        mIntrinsic(false), mReturn(nullptr) {}
408    ~FunctionSpecification();
409
410    Function* getFunction() const { return mFunction; }
411    bool isInternal() const { return mInternal; }
412    bool isIntrinsic() const { return mIntrinsic; }
413    std::string getAttribute() const { return mAttribute; }
414    std::string getTest() const { return mTest; }
415    std::string getPrecisionLimit() const { return mPrecisionLimit; }
416
417    const std::vector<FunctionPermutation*>& getPermutations() const { return mPermutations; }
418
419    std::string getName(int replacementIndexes[MAX_REPLACEABLES]) const;
420    void getReturn(int replacementIndexes[MAX_REPLACEABLES], std::string* retType,
421                   int* lineNumber) const;
422    size_t getNumberOfParams() const { return mParameters.size(); }
423    void getParam(size_t index, int replacementIndexes[MAX_REPLACEABLES], std::string* type,
424                  std::string* name, std::string* testOption, int* lineNumber) const;
425    void getInlines(int replacementIndexes[MAX_REPLACEABLES],
426                    std::vector<std::string>* inlines) const;
427
428    // Parse the "test:" line.
429    void parseTest(Scanner* scanner);
430
431    // Return true if we need to generate tests for this function.
432    bool hasTests(unsigned int versionOfTestFiles) const;
433
434    bool hasInline() const { return mInline.size() > 0; }
435
436    /* Return true if this function can be overloaded.  This is added by default to all
437     * specifications, so except for the very few exceptions that start the attributes
438     * with an '=' to avoid this, we'll return true.
439     */
440    bool isOverloadable() const {
441        return mAttribute.empty() || mAttribute[0] != '=';
442    }
443
444    /* Check if RST_i is present in 's' and report an error if 'allow' is false
445     * or the i-th replacement list is not a valid candidate for RST_i
446     * replacement
447     */
448    void checkRSTPatternValidity(const std::string &s, bool allow, Scanner *scanner);
449
450    // Parse a function specification and add it to specFile.
451    static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
452};
453
454/* A concrete version of a function specification, where all placeholders have been replaced by
455 * actual values.
456 */
457class FunctionPermutation {
458private:
459    // These are the expanded version of those found on FunctionSpecification
460    std::string mName;
461    std::string mNameTrunk;  // The name without any expansion, e.g. convert
462    std::string mTest;       // How to test.  One of "scalar", "vector", "noverify", "limited", and
463                             // "none".
464    std::string mPrecisionLimit;  // Maximum precision required when checking output of this
465                                  // function.
466
467    // The parameters of the function.  This does not include the return type.  Owned.
468    std::vector<ParameterDefinition*> mParams;
469    // The return type.  nullptr if a void function.  Owned.
470    ParameterDefinition* mReturn;
471
472    // The number of input and output parameters.  mOutputCount counts the return type.
473    int mInputCount;
474    int mOutputCount;
475
476    // Whether one of the output parameters is a float.
477    bool mHasFloatAnswers;
478
479    // The inline code that implements this function.  Will be empty if not an inline.
480    std::vector<std::string> mInline;
481
482public:
483    FunctionPermutation(Function* function, FunctionSpecification* specification,
484                        int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner);
485    ~FunctionPermutation();
486
487    std::string getName() const { return mName; }
488    std::string getNameTrunk() const { return mNameTrunk; }
489    std::string getTest() const { return mTest; }
490    std::string getPrecisionLimit() const { return mPrecisionLimit; }
491
492    const std::vector<std::string>& getInline() const { return mInline; }
493    const ParameterDefinition* getReturn() const { return mReturn; }
494    int getInputCount() const { return mInputCount; }
495    int getOutputCount() const { return mOutputCount; }
496    bool hasFloatAnswers() const { return mHasFloatAnswers; }
497
498    const std::vector<ParameterDefinition*> getParams() const { return mParams; }
499};
500
501// An entire spec file and the methods to process it.
502class SpecFile {
503private:
504    std::string mSpecFileName;
505    std::string mHeaderFileName;
506    std::string mDetailedDocumentationUrl;
507    std::string mBriefDescription;
508    std::vector<std::string> mFullDescription;
509    // Text to insert as-is in the generated header.
510    std::vector<std::string> mVerbatimInclude;
511
512    /* The constants, types, and functions specifications declared in this
513     *  file, in the order they are found in the file.  This matters for
514     * header generation, as some types and inline functions depend
515     * on each other.  Pointers not owned.
516     */
517    std::list<ConstantSpecification*> mConstantSpecificationsList;
518    std::list<TypeSpecification*> mTypeSpecificationsList;
519    std::list<FunctionSpecification*> mFunctionSpecificationsList;
520
521    /* The constants, types, and functions that are documented in this file.
522     * In very rare cases, specifications for an API are split across multiple
523     * files, e.g. currently for ClearObject().  The documentation for
524     * that function must be found in the first spec file encountered, so the
525     * order of the files on the command line matters.
526     */
527    std::map<std::string, Constant*> mDocumentedConstants;
528    std::map<std::string, Type*> mDocumentedTypes;
529    std::map<std::string, Function*> mDocumentedFunctions;
530
531public:
532    explicit SpecFile(const std::string& specFileName);
533
534    std::string getSpecFileName() const { return mSpecFileName; }
535    std::string getHeaderFileName() const { return mHeaderFileName; }
536    std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; }
537    const std::string getBriefDescription() const { return mBriefDescription; }
538    const std::vector<std::string>& getFullDescription() const { return mFullDescription; }
539    const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; }
540
541    const std::list<ConstantSpecification*>& getConstantSpecifications() const {
542        return mConstantSpecificationsList;
543    }
544    const std::list<TypeSpecification*>& getTypeSpecifications() const {
545        return mTypeSpecificationsList;
546    }
547    const std::list<FunctionSpecification*>& getFunctionSpecifications() const {
548        return mFunctionSpecificationsList;
549    }
550    const std::map<std::string, Constant*>& getDocumentedConstants() const {
551        return mDocumentedConstants;
552    }
553    const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; }
554    const std::map<std::string, Function*>& getDocumentedFunctions() const {
555        return mDocumentedFunctions;
556    }
557
558    bool hasSpecifications() const {
559        return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() ||
560               !mDocumentedFunctions.empty();
561    }
562
563    bool readSpecFile(unsigned int maxApiLevel);
564
565    /* These are called by the parser to keep track of the specifications defined in this file.
566     * hasDocumentation is true if this specification containes the documentation.
567     */
568    void addConstantSpecification(ConstantSpecification* spec, bool hasDocumentation);
569    void addTypeSpecification(TypeSpecification* spec, bool hasDocumentation);
570    void addFunctionSpecification(FunctionSpecification* spec, bool hasDocumentation);
571};
572
573// The collection of all the spec files.
574class SystemSpecification {
575private:
576    std::vector<SpecFile*> mSpecFiles;
577
578    /* Entries in the table of contents.  We accumulate them in a map to sort them.
579     * Pointers are owned.
580     */
581    std::map<std::string, Constant*> mConstants;
582    std::map<std::string, Type*> mTypes;
583    std::map<std::string, Function*> mFunctions;
584
585public:
586    ~SystemSpecification();
587
588    /* These are called the parser to create unique instances per name.  Set *created to true
589     * if the named specification did not already exist.
590     */
591    Constant* findOrCreateConstant(const std::string& name, bool* created);
592    Type* findOrCreateType(const std::string& name, bool* created);
593    Function* findOrCreateFunction(const std::string& name, bool* created);
594
595    /* Parse the spec file and create the object hierarchy, adding a pointer to mSpecFiles.
596     * We won't include information passed the specified level.
597     */
598    bool readSpecFile(const std::string& fileName, unsigned int maxApiLevel);
599    // Generate all the files.
600    bool generateFiles(unsigned int maxApiLevel) const;
601
602    const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; }
603    const std::map<std::string, Constant*>& getConstants() const { return mConstants; }
604    const std::map<std::string, Type*>& getTypes() const { return mTypes; }
605    const std::map<std::string, Function*>& getFunctions() const { return mFunctions; }
606
607    // Returns "<a href='...'> for the named specification, or empty if not found.
608    std::string getHtmlAnchor(const std::string& name) const;
609
610    // Returns the maximum API level specified in any spec file.
611    unsigned int getMaximumApiLevel();
612};
613
614// Singleton that represents the collection of all the specs we're processing.
615extern SystemSpecification systemSpecification;
616
617// Table of equivalences of numerical types.
618extern const NumericalType TYPES[];
619extern const int NUM_TYPES;
620
621/* Given a renderscript type (string) calculate the vector size and base type. If the type
622 * is not a vector the vector size is 1 and baseType is just the type itself.
623 */
624void getVectorSizeAndBaseType(const std::string& type, std::string& vectorSize,
625                              std::string& baseType);
626
627#endif  // ANDROID_RS_API_GENERATOR_SPECIFICATION_H
628