1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_RS_API_GENERATOR_SPECIFICATION_H 18 #define ANDROID_RS_API_GENERATOR_SPECIFICATION_H 19 20 // See Generator.cpp for documentation of the .spec file format. 21 22 #include <climits> 23 #include <fstream> 24 #include <list> 25 #include <map> 26 #include <string> 27 #include <vector> 28 29 class Constant; 30 class ConstantSpecification; 31 class Function; 32 class FunctionPermutation; 33 class FunctionSpecification; 34 class SpecFile; 35 class Specification; 36 class Scanner; 37 class SystemSpecification; 38 class Type; 39 class TypeSpecification; 40 41 enum NumberKind { SIGNED_INTEGER, UNSIGNED_INTEGER, FLOATING_POINT }; 42 43 // Table of type equivalences. 44 struct NumericalType { 45 const char* specType; // Name found in the .spec file 46 const char* rsDataType; // RS data type 47 const char* cType; // Type in a C file 48 const char* javaType; // Type in a Java file 49 NumberKind kind; 50 /* For integers, number of bits of the number, excluding the sign bit. 51 * For floats, number of implied bits of the mantissa. 52 */ 53 int significantBits; 54 // For floats, number of bits of the exponent. 0 for integer types. 55 int exponentBits; 56 }; 57 58 /* Corresponds to one parameter line in a .spec file. These will be parsed when 59 * we instantiate the FunctionPermutation(s) that correspond to one FunctionSpecification. 60 */ 61 struct ParameterEntry { 62 std::string type; 63 std::string name; 64 /* Optional information on how to generate test values for this parameter. Can be: 65 * - range(low, high): Generates values between these two limits only. 66 * - above(other_parameter): The values must be greater than those of the named parameter. 67 * Used for clamp. 68 * - compatible(type): The values must also be fully representable in the specified type. 69 * - conditional: Don't verify this value the function return NaN. 70 */ 71 std::string testOption; 72 std::string documentation; 73 int lineNumber; 74 }; 75 76 /* Information about a parameter to a function. The values of all the fields should only be set by 77 * parseParameterDefinition. 78 */ 79 struct ParameterDefinition { 80 std::string rsType; // The Renderscript type, e.g. "uint3" 81 std::string rsBaseType; // As above but without the number, e.g. "uint" 82 std::string javaBaseType; // The type we need to declare in Java, e.g. "unsigned int" 83 std::string specType; // The type found in the spec, e.g. "f16" 84 bool isFloatType; // True if it's a floating point value 85 /* The number of entries in the vector. It should be either "1", "2", "3", or "4". It's also 86 * "1" for scalars. 87 */ 88 std::string mVectorSize; 89 /* The space the vector takes in an array. It's the same as the vector size, except for size 90 * "3", where the width is "4". 91 */ 92 std::string vectorWidth; 93 94 std::string specName; // e.g. x, as found in the spec file 95 std::string variableName; // e.g. inX, used both in .rs and .java 96 std::string rsAllocName; // e.g. gAllocInX 97 std::string javaAllocName; // e.g. inX 98 std::string javaArrayName; // e.g. arrayInX 99 std::string doubleVariableName; // e.g. inXDouble, used in .java for storing Float16 parameters 100 // in double. 101 102 // If non empty, the mininum and maximum values to be used when generating the test data. 103 std::string minValue; 104 std::string maxValue; 105 /* If non empty, contains the name of another parameter that should be smaller or equal to this 106 * parameter, i.e. value(smallerParameter) <= value(this). This is used when testing clamp. 107 */ 108 std::string smallerParameter; 109 110 bool isOutParameter; // True if this parameter returns data from the script. 111 bool undefinedIfOutIsNan; // If true, we don't validate if 'out' is NaN. 112 113 int typeIndex; // Index in the TYPES array. Negative if not found in the array. 114 int compatibleTypeIndex; // Index in TYPES for which the test data must also fit. 115 116 /* Fill this object from the type, name, and testOption. 117 * isReturn is true if we're processing the "return:" 118 */ 119 void parseParameterDefinition(const std::string& type, const std::string& name, 120 const std::string& testOption, int lineNumber, bool isReturn, 121 Scanner* scanner); 122 isFloat16ParameterParameterDefinition123 bool isFloat16Parameter() const { return specType.compare("f16") == 0; } 124 }; 125 126 struct VersionInfo { 127 /* The range of versions a specification applies to. Zero if there's no restriction, 128 * so an API that became available at 12 and is still valid would have min:12 max:0. 129 * If non zero, both versions should be at least 9, the API level that introduced 130 * RenderScript. 131 */ 132 unsigned int minVersion; 133 unsigned int maxVersion; 134 // Either 0, 32 or 64. If 0, this definition is valid for both 32 and 64 bits. 135 int intSize; 136 VersionInfoVersionInfo137 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. */ includesVersionVersionInfo144 bool includesVersion(int target) const { 145 return (minVersion == 0 || target >= minVersion) && 146 (maxVersion == 0 || target <= maxVersion); 147 } 148 149 static constexpr unsigned int kUnreleasedVersion = UINT_MAX; 150 }; 151 152 // We have three type of definitions 153 class Definition { 154 protected: 155 std::string mName; 156 /* If greater than 0, this definition is deprecated. It's the API level at which 157 * we added the deprecation warning. 158 */ 159 int mDeprecatedApiLevel; 160 std::string mDeprecatedMessage; // Optional specific warning if the API is deprecated 161 bool mHidden; // True if it should not be documented 162 std::string mSummary; // A one-line description 163 std::vector<std::string> mDescription; // The comments to be included in the header 164 std::string mUrl; // The URL of the detailed documentation 165 int mFinalVersion; // API level at which this API was removed, 0 if API is still valid 166 167 public: 168 Definition(const std::string& name); 169 getName()170 std::string getName() const { return mName; } deprecated()171 bool deprecated() const { return mDeprecatedApiLevel > 0; } getDeprecatedApiLevel()172 int getDeprecatedApiLevel() const { return mDeprecatedApiLevel; } getDeprecatedMessage()173 std::string getDeprecatedMessage() const { return mDeprecatedMessage; } hidden()174 bool hidden() const { return mHidden; } getSummary()175 std::string getSummary() const { return mSummary; } getDescription()176 const std::vector<std::string>& getDescription() const { return mDescription; } getUrl()177 std::string getUrl() const { return mUrl; } getFinalVersion()178 int getFinalVersion() const { return mFinalVersion; } 179 180 void scanDocumentationTags(Scanner* scanner, bool firstOccurence, const SpecFile* specFile); 181 // Keep track of the final version of this API, if any. 182 void updateFinalVersion(const VersionInfo& info); 183 }; 184 185 /* Represents a constant, like M_PI. This is a grouping of the version specific specifications. 186 * We'll only have one instance of Constant for each name. 187 */ 188 class Constant : public Definition { 189 private: 190 std::vector<ConstantSpecification*> mSpecifications; // Owned 191 192 public: Constant(const std::string & name)193 Constant(const std::string& name) : Definition(name) {} 194 ~Constant(); 195 getSpecifications()196 const std::vector<ConstantSpecification*> getSpecifications() const { return mSpecifications; } 197 // This method should only be called by the scanning code. addSpecification(ConstantSpecification * spec)198 void addSpecification(ConstantSpecification* spec) { mSpecifications.push_back(spec); } 199 }; 200 201 /* Represents a type, like "float4". This is a grouping of the version specific specifications. 202 * We'll only have one instance of Type for each name. 203 */ 204 class Type : public Definition { 205 private: 206 std::vector<TypeSpecification*> mSpecifications; // Owned 207 208 public: Type(const std::string & name)209 Type(const std::string& name) : Definition(name) {} 210 ~Type(); 211 getSpecifications()212 const std::vector<TypeSpecification*> getSpecifications() const { return mSpecifications; } 213 // This method should only be called by the scanning code. addSpecification(TypeSpecification * spec)214 void addSpecification(TypeSpecification* spec) { mSpecifications.push_back(spec); } 215 }; 216 217 /* Represents a function, like "clamp". Even though the spec file contains many entries for clamp, 218 * we'll only have one clamp instance. 219 */ 220 class Function : public Definition { 221 private: 222 // mName in the base class contains the lower case name, e.g. native_log 223 std::string mCapitalizedName; // The capitalized name, e.g. NativeLog 224 225 // The unique parameters between all the specifications. NOT OWNED. 226 std::vector<ParameterEntry*> mParameters; 227 std::string mReturnDocumentation; 228 229 std::vector<FunctionSpecification*> mSpecifications; // Owned 230 231 public: 232 Function(const std::string& name); 233 ~Function(); 234 getCapitalizedName()235 std::string getCapitalizedName() const { return mCapitalizedName; } getParameters()236 const std::vector<ParameterEntry*>& getParameters() const { return mParameters; } getReturnDocumentation()237 std::string getReturnDocumentation() const { return mReturnDocumentation; } getSpecifications()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); addSpecification(FunctionSpecification * spec)245 void addSpecification(FunctionSpecification* spec) { mSpecifications.push_back(spec); } 246 }; 247 248 /* Base class for TypeSpecification, ConstantSpecification, and FunctionSpecification. 249 * A specification can be specific to a range of RenderScript version or 32bits vs 64 bits. 250 * This base class contains code to parse and store this version information. 251 */ 252 class Specification { 253 protected: 254 VersionInfo mVersionInfo; 255 void scanVersionInfo(Scanner* scanner); 256 257 public: getVersionInfo()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 */ 264 class ConstantSpecification : public Specification { 265 private: 266 Constant* mConstant; // Not owned 267 268 std::string mValue; // E.g. "3.1415" 269 std::string mType; // E.g. "float" 270 public: ConstantSpecification(Constant * constant)271 ConstantSpecification(Constant* constant) : mConstant(constant) {} 272 getConstant()273 Constant* getConstant() const { return mConstant; } getValue()274 std::string getValue() const { return mValue; } getType()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 281 enum 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 */ 291 class TypeSpecification : public Specification { 292 private: 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 310 public: TypeSpecification(Type * type)311 TypeSpecification(Type* type) : mType(type) {} 312 getType()313 Type* getType() const { return mType; } getKind()314 TypeKind getKind() const { return mKind; } getSimpleType()315 std::string getSimpleType() const { return mSimpleType; } getStructName()316 std::string getStructName() const { return mStructName; } getFields()317 const std::vector<std::string>& getFields() const { return mFields; } getFieldComments()318 const std::vector<std::string>& getFieldComments() const { return mFieldComments; } getAttribute()319 std::string getAttribute() const { return mAttribute; } getEnumName()320 std::string getEnumName() const { return mEnumName; } getValues()321 const std::vector<std::string>& getValues() const { return mValues; } getValueComments()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. 329 const 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 */ 336 class FunctionSpecification : public Specification { 337 private: 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 405 public: FunctionSpecification(Function * function)406 FunctionSpecification(Function* function) : mFunction(function), mInternal(false), 407 mIntrinsic(false), mReturn(nullptr) {} 408 ~FunctionSpecification(); 409 getFunction()410 Function* getFunction() const { return mFunction; } isInternal()411 bool isInternal() const { return mInternal; } isIntrinsic()412 bool isIntrinsic() const { return mIntrinsic; } getAttribute()413 std::string getAttribute() const { return mAttribute; } getTest()414 std::string getTest() const { return mTest; } getPrecisionLimit()415 std::string getPrecisionLimit() const { return mPrecisionLimit; } 416 getPermutations()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; getNumberOfParams()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 hasInline()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 */ isOverloadable()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 */ 457 class FunctionPermutation { 458 private: 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 482 public: 483 FunctionPermutation(Function* function, FunctionSpecification* specification, 484 int replacementIndexes[MAX_REPLACEABLES], Scanner* scanner); 485 ~FunctionPermutation(); 486 getName()487 std::string getName() const { return mName; } getNameTrunk()488 std::string getNameTrunk() const { return mNameTrunk; } getTest()489 std::string getTest() const { return mTest; } getPrecisionLimit()490 std::string getPrecisionLimit() const { return mPrecisionLimit; } 491 getInline()492 const std::vector<std::string>& getInline() const { return mInline; } getReturn()493 const ParameterDefinition* getReturn() const { return mReturn; } getInputCount()494 int getInputCount() const { return mInputCount; } getOutputCount()495 int getOutputCount() const { return mOutputCount; } hasFloatAnswers()496 bool hasFloatAnswers() const { return mHasFloatAnswers; } 497 getParams()498 const std::vector<ParameterDefinition*> getParams() const { return mParams; } 499 }; 500 501 // An entire spec file and the methods to process it. 502 class SpecFile { 503 private: 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 531 public: 532 explicit SpecFile(const std::string& specFileName); 533 getSpecFileName()534 std::string getSpecFileName() const { return mSpecFileName; } getHeaderFileName()535 std::string getHeaderFileName() const { return mHeaderFileName; } getDetailedDocumentationUrl()536 std::string getDetailedDocumentationUrl() const { return mDetailedDocumentationUrl; } getBriefDescription()537 const std::string getBriefDescription() const { return mBriefDescription; } getFullDescription()538 const std::vector<std::string>& getFullDescription() const { return mFullDescription; } getVerbatimInclude()539 const std::vector<std::string>& getVerbatimInclude() const { return mVerbatimInclude; } 540 getConstantSpecifications()541 const std::list<ConstantSpecification*>& getConstantSpecifications() const { 542 return mConstantSpecificationsList; 543 } getTypeSpecifications()544 const std::list<TypeSpecification*>& getTypeSpecifications() const { 545 return mTypeSpecificationsList; 546 } getFunctionSpecifications()547 const std::list<FunctionSpecification*>& getFunctionSpecifications() const { 548 return mFunctionSpecificationsList; 549 } getDocumentedConstants()550 const std::map<std::string, Constant*>& getDocumentedConstants() const { 551 return mDocumentedConstants; 552 } getDocumentedTypes()553 const std::map<std::string, Type*>& getDocumentedTypes() const { return mDocumentedTypes; } getDocumentedFunctions()554 const std::map<std::string, Function*>& getDocumentedFunctions() const { 555 return mDocumentedFunctions; 556 } 557 hasSpecifications()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. 574 class SystemSpecification { 575 private: 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 585 public: 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(bool forVerification, unsigned int maxApiLevel) const; 601 getSpecFiles()602 const std::vector<SpecFile*>& getSpecFiles() const { return mSpecFiles; } getConstants()603 const std::map<std::string, Constant*>& getConstants() const { return mConstants; } getTypes()604 const std::map<std::string, Type*>& getTypes() const { return mTypes; } getFunctions()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. 615 extern SystemSpecification systemSpecification; 616 617 // Table of equivalences of numerical types. 618 extern const NumericalType TYPES[]; 619 extern 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 */ 624 void getVectorSizeAndBaseType(const std::string& type, std::string& vectorSize, 625 std::string& baseType); 626 627 #endif // ANDROID_RS_API_GENERATOR_SPECIFICATION_H 628