blob: 9e1b2ee8fa56a0d2b1a8de10315fc7c26a8ce65e [file] [log] [blame]
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -07001/*
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
Yang Ni12398d82015-09-18 14:57:07 -070022#include <climits>
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -070023#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
Pirama Arumuga Nainar3b2be142016-02-29 13:35:18 -080099 std::string doubleVariableName; // e.g. inXDouble, used in .java for storing Float16 parameters
100 // in double.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700101
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);
Pirama Arumuga Nainar3b2be142016-02-29 13:35:18 -0800122
123 bool isFloat16Parameter() const { return specType.compare("f16") == 0; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700124};
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 */
Yang Ni12398d82015-09-18 14:57:07 -0700132 unsigned int minVersion;
133 unsigned int maxVersion;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700134 // 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) {}
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700138 /* 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 */
Yang Ni12398d82015-09-18 14:57:07 -0700142 bool scan(Scanner* scanner, unsigned int maxApiLevel);
Jean-Luc Brouillet36090672015-04-07 15:15:53 -0700143 /* 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 }
Yang Ni12398d82015-09-18 14:57:07 -0700148
149 static constexpr unsigned int kUnreleasedVersion = UINT_MAX;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700150};
151
152// We have three type of definitions
153class Definition {
154protected:
155 std::string mName;
Jean-Luc Brouillet36e2be52015-04-30 14:41:24 -0700156 /* 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;
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700160 std::string mDeprecatedMessage; // Optional specific warning if the API is deprecated
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700161 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
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700165 int mFinalVersion; // API level at which this API was removed, 0 if API is still valid
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700166
167public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700168 Definition(const std::string& name);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700169
170 std::string getName() const { return mName; }
Jean-Luc Brouillet36e2be52015-04-30 14:41:24 -0700171 bool deprecated() const { return mDeprecatedApiLevel > 0; }
172 int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; }
Jean-Luc Brouillet4a730042015-04-02 16:15:25 -0700173 std::string getDeprecatedMessage() const { return mDeprecatedMessage; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700174 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; }
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700178 int getFinalVersion() const { return mFinalVersion; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700179
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700180 void scanDocumentationTags(Scanner* scanner, bool firstOccurence, const SpecFile* specFile);
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700181 // Keep track of the final version of this API, if any.
182 void updateFinalVersion(const VersionInfo& info);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700183};
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:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700193 Constant(const std::string& name) : Definition(name) {}
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700194 ~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:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700209 Type(const std::string& name) : Definition(name) {}
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700210 ~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:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700232 Function(const std::string& name);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700233 ~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
David Grosscb25a812017-02-10 15:10:52 -0800261/* Defines one of the many variations of a constant. There's a one to one correspondence between
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700262 * ConstantSpecification objects and entries in the spec file.
263 */
264class ConstantSpecification : public Specification {
265private:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700266 Constant* mConstant; // Not owned
267
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700268 std::string mValue; // E.g. "3.1415"
David Grosscb25a812017-02-10 15:10:52 -0800269 std::string mType; // E.g. "float"
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700270public:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700271 ConstantSpecification(Constant* constant) : mConstant(constant) {}
272
273 Constant* getConstant() const { return mConstant; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700274 std::string getValue() const { return mValue; }
David Grosscb25a812017-02-10 15:10:52 -0800275 std::string getType() const { return mType; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700276
277 // Parse a constant specification and add it to specFile.
Yang Ni12398d82015-09-18 14:57:07 -0700278 static void scanConstantSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700279};
280
281enum TypeKind {
282 SIMPLE,
Stephen Hinesca51c782015-08-25 23:43:34 -0700283 RS_OBJECT,
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700284 STRUCT,
285 ENUM,
286};
287
David Grosscb25a812017-02-10 15:10:52 -0800288/* Defines one of the many variations of a type. There's a one to one correspondence between
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700289 * TypeSpecification objects and entries in the spec file.
290 */
291class TypeSpecification : public Specification {
292private:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700293 Type* mType; // Not owned
294
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700295 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
Jean-Luc Brouillet36e2be52015-04-30 14:41:24 -0700304 std::string mAttribute; // Some structures may have attributes
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700305
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:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700311 TypeSpecification(Type* type) : mType(type) {}
312
313 Type* getType() const { return mType; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700314 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; }
Jean-Luc Brouillet36e2be52015-04-30 14:41:24 -0700319 std::string getAttribute() const { return mAttribute; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700320 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.
Yang Ni12398d82015-09-18 14:57:07 -0700325 static void scanTypeSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700326};
327
328// Maximum number of placeholders (like #1, #2) in function specifications.
329const int MAX_REPLACEABLES = 4;
330
David Grosscb25a812017-02-10 15:10:52 -0800331/* Defines one of the many variations of the function. There's a one to one correspondence between
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700332 * 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:
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700338 Function* mFunction; // Not owned
339
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700340 /* 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.
Jean-Luc Brouillet66fea242015-04-09 16:47:59 -0700352 * "": Don't test. This is the default.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700353 */
354 std::string mTest;
Yang Ni12398d82015-09-18 14:57:07 -0700355 bool mInternal; // Internal. Not visible to users. (Default: false)
356 bool mIntrinsic; // Compiler intrinsic that is lowered to an internal API.
357 // (Default: false)
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700358 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
Pirama Arumuga Nainar43d758c2015-11-13 12:54:42 -0800365 // 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700369 /* 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;
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700381 ParameterEntry* mReturn; // The return type. The name should be empty. Owned.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700382 std::vector<ParameterEntry*> mParameters; // The parameters. Owned.
383 std::vector<std::string> mInline; // The inline code to be included in the header
384
Pirama Arumuga Nainar43d758c2015-11-13 12:54:42 -0800385 /* 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.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700391 */
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
Pirama Arumuga Nainar43d758c2015-11-13 12:54:42 -0800397 // 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700402 // Fill the mPermutations field.
403 void createPermutations(Function* function, Scanner* scanner);
404
405public:
Yang Ni12398d82015-09-18 14:57:07 -0700406 FunctionSpecification(Function* function) : mFunction(function), mInternal(false),
407 mIntrinsic(false), mReturn(nullptr) {}
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700408 ~FunctionSpecification();
409
Jean-Luc Brouillet67923a92015-05-12 15:38:27 -0700410 Function* getFunction() const { return mFunction; }
Yang Ni12398d82015-09-18 14:57:07 -0700411 bool isInternal() const { return mInternal; }
412 bool isIntrinsic() const { return mIntrinsic; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700413 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.
Yang Ni12398d82015-09-18 14:57:07 -0700432 bool hasTests(unsigned int versionOfTestFiles) const;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700433
Jean-Luc Brouillet36090672015-04-07 15:15:53 -0700434 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
Pirama Arumuga Nainar43d758c2015-11-13 12:54:42 -0800444 /* 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700450 // Parse a function specification and add it to specFile.
Yang Ni12398d82015-09-18 14:57:07 -0700451 static void scanFunctionSpecification(Scanner* scanner, SpecFile* specFile, unsigned int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700452};
453
454/* A concrete version of a function specification, where all placeholders have been replaced by
455 * actual values.
456 */
457class FunctionPermutation {
458private:
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700459 // 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
Jean-Luc Brouillet66fea242015-04-09 16:47:59 -0700492 const std::vector<std::string>& getInline() const { return mInline; }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700493 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
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700512 /* The constants, types, and functions specifications declared in this
513 * file, in the order they are found in the file. This matters for
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700514 * header generation, as some types and inline functions depend
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700515 * on each other. Pointers not owned.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700516 */
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700517 std::list<ConstantSpecification*> mConstantSpecificationsList;
518 std::list<TypeSpecification*> mTypeSpecificationsList;
519 std::list<FunctionSpecification*> mFunctionSpecificationsList;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700520
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700521 /* 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;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700530
531public:
532 explicit SpecFile(const std::string& specFileName);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700533
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
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700541 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 }
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700557
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700558 bool hasSpecifications() const {
559 return !mDocumentedConstants.empty() || !mDocumentedTypes.empty() ||
560 !mDocumentedFunctions.empty();
561 }
562
Yang Ni12398d82015-09-18 14:57:07 -0700563 bool readSpecFile(unsigned int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700564
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700565 /* 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);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700571};
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.
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700579 * Pointers are owned.
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700580 */
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();
Jean-Luc Brouillet7c078542015-03-23 16:16:08 -0700587
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
Jean-Luc Brouillet2217eb72015-04-24 14:41:48 -0700595 /* 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 */
Yang Ni12398d82015-09-18 14:57:07 -0700598 bool readSpecFile(const std::string& fileName, unsigned int maxApiLevel);
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700599 // Generate all the files.
Yang Ni12398d82015-09-18 14:57:07 -0700600 bool generateFiles(bool forVerification, unsigned int maxApiLevel) const;
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700601
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;
Jean-Luc Brouillet36090672015-04-07 15:15:53 -0700609
610 // Returns the maximum API level specified in any spec file.
Yang Ni12398d82015-09-18 14:57:07 -0700611 unsigned int getMaximumApiLevel();
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700612};
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
Dean De Leo9309a062015-11-25 13:37:05 +0000621/* 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
Jean-Luc Brouilletc5184e22015-03-13 13:51:24 -0700627#endif // ANDROID_RS_API_GENERATOR_SPECIFICATION_H