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