1 /* 2 * Copyright (C) 2016 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 TYPE_H_ 18 19 #define TYPE_H_ 20 21 #include <android-base/macros.h> 22 #include <utils/Errors.h> 23 #include <set> 24 #include <string> 25 #include <unordered_map> 26 #include <unordered_set> 27 #include <vector> 28 29 #include "DocComment.h" 30 #include "Reference.h" 31 32 namespace android { 33 34 struct ConstantExpression; 35 struct Formatter; 36 struct FQName; 37 struct ScalarType; 38 struct Scope; 39 40 struct Type : DocCommentable { 41 Type(Scope* parent, const std::string& definedName); 42 virtual ~Type(); 43 44 virtual bool isArray() const; 45 virtual bool isBitField() const; 46 virtual bool isCompoundType() const; 47 virtual bool isEnum() const; 48 virtual bool isHandle() const; 49 virtual bool isInterface() const; 50 virtual bool isNamedType() const; 51 virtual bool isMemory() const; 52 virtual bool isPointer() const; 53 virtual bool isScope() const; 54 virtual bool isScalar() const; 55 virtual bool isString() const; 56 virtual bool isTemplatedType() const; 57 virtual bool isTypeDef() const; 58 virtual bool isVector() const; 59 virtual bool isFmq() const; 60 61 // Resolves the type by unwrapping typedefs 62 Type* resolve(); 63 virtual const Type* resolve() const; 64 65 // All types defined in this type. 66 std::vector<Type*> getDefinedTypes(); 67 virtual std::vector<const Type*> getDefinedTypes() const; 68 69 // All types referenced in this type. 70 std::vector<Reference<Type>*> getReferences(); 71 virtual std::vector<const Reference<Type>*> getReferences() const; 72 73 // All constant expressions referenced in this type. 74 std::vector<ConstantExpression*> getConstantExpressions(); 75 virtual std::vector<const ConstantExpression*> getConstantExpressions() const; 76 77 // All types referenced in this type that must have completed 78 // definiton before being referenced. 79 std::vector<Reference<Type>*> getStrongReferences(); 80 virtual std::vector<const Reference<Type>*> getStrongReferences() const; 81 82 // Indicate stage of parsing. 83 enum class ParseStage { 84 // Indicate that the source file is being parsed and this object is being filled. 85 PARSE, 86 // Indicate that all source files are parsed, and program is working on type dependencies 87 // and validation. 88 POST_PARSE, 89 // Indicate that parsing is completed, and program is in code-generation stage. 90 COMPLETED, 91 }; 92 93 // Proceeds recursive pass 94 // Makes sure to visit each node only once. 95 // If mParseStage < stage, object is not ready for this recursivePass() call 96 // yet, and function will return error. 97 status_t recursivePass(ParseStage stage, const std::function<status_t(Type*)>& func, 98 std::unordered_set<const Type*>* visited); 99 status_t recursivePass(ParseStage stage, const std::function<status_t(const Type*)>& func, 100 std::unordered_set<const Type*>* visited) const; 101 102 // Recursive tree pass that completes type declarations 103 // that depend on super types 104 virtual status_t resolveInheritance(); 105 106 // Recursive tree pass that validates all type-related 107 // syntax restrictions 108 virtual status_t validate() const; 109 110 // Recursive tree pass checkAcyclic return type. 111 // Stores cycle end for nice error messages. 112 struct CheckAcyclicStatus { 113 CheckAcyclicStatus(status_t status, const Type* cycleEnd = nullptr); 114 115 status_t status; 116 117 // If a cycle is found, stores the end of cycle. 118 // While going back in recursion, this is used to stop printing the cycle. 119 const Type* cycleEnd; 120 }; 121 122 // Recursive tree pass that ensures that type definitions and references 123 // are acyclic and builds reversed topological order of the types. 124 // If some cases allow using of incomplete types, these cases are to be 125 // declared in Type::getStrongReferences. 126 CheckAcyclicStatus topologicalOrder(std::unordered_map<const Type*, size_t>* reversedOrder, 127 std::unordered_set<const Type*>* stack) const; 128 129 // Checks following C++ restriction on forward declaration: 130 // inner struct could be forward declared only inside its parent. 131 status_t checkForwardReferenceRestrictions(const Reference<Type>& ref) const; 132 133 virtual const ScalarType *resolveToScalarType() const; 134 135 virtual std::string typeName() const = 0; 136 137 bool isValidEnumStorageType() const; 138 virtual bool isElidableType() const; 139 140 virtual bool canCheckEquality() const; 141 bool canCheckEquality(std::unordered_set<const Type*>* visited) const; 142 virtual bool deepCanCheckEquality(std::unordered_set<const Type*>* visited) const; 143 144 // ParseStage can only be incremented. 145 ParseStage getParseStage() const; 146 void setParseStage(ParseStage stage); 147 148 Scope* parent(); 149 const Scope* parent() const; 150 151 const std::string& definedName() const; 152 153 enum StorageMode { 154 StorageMode_Stack, 155 StorageMode_Argument, 156 StorageMode_Result, 157 }; 158 159 // specifyNamespaces: whether to specify namespaces for built-in types 160 virtual std::string getCppType( 161 StorageMode mode, 162 bool specifyNamespaces) const; 163 164 std::string decorateCppName( 165 const std::string &name, 166 StorageMode mode, 167 bool specifyNamespaces) const; 168 169 std::string getCppStackType(bool specifyNamespaces = true) const; 170 171 std::string getCppResultType(bool specifyNamespaces = true) const; 172 173 std::string getCppArgumentType(bool specifyNamespaces = true) const; 174 175 std::string getCppTypeCast(const std::string& objName, 176 bool specifyNamespaces = true) const; 177 178 // For an array type, dimensionality information will be accumulated at the 179 // end of the returned string. 180 // if forInitializer == true, actual dimensions are included, i.e. [3][5], 181 // otherwise (and by default), they are omitted, i.e. [][]. 182 virtual std::string getJavaType(bool forInitializer = false) const; 183 184 // Identical to getJavaType() for most types, except: primitives, in which 185 // case the wrapper type is returned, and generics (such as ArrayList<?>), 186 // where the type specialization is omitted to facilitate use of 187 // instanceof or class.isInstance(). 188 virtual std::string getJavaTypeClass() const; 189 190 virtual std::string getJavaTypeCast(const std::string& objName) const; 191 virtual std::string getJavaSuffix() const; 192 193 virtual std::string getVtsType() const; 194 virtual std::string getVtsValueName() const; 195 196 enum ErrorMode { 197 ErrorMode_Goto, 198 ErrorMode_Break, 199 ErrorMode_Return, 200 ErrorMode_ReturnNothing, 201 }; 202 virtual void emitReaderWriter( 203 Formatter &out, 204 const std::string &name, 205 const std::string &parcelObj, 206 bool parcelObjIsPointer, 207 bool isReader, 208 ErrorMode mode) const; 209 210 virtual void emitReaderWriterEmbedded( 211 Formatter &out, 212 size_t depth, 213 const std::string &name, 214 const std::string &sanitizedName, 215 bool nameIsPointer, 216 const std::string &parcelObj, 217 bool parcelObjIsPointer, 218 bool isReader, 219 ErrorMode mode, 220 const std::string &parentName, 221 const std::string &offsetText) const; 222 223 virtual void emitDump( 224 Formatter &out, 225 const std::string &streamName, 226 const std::string &name) const; 227 228 virtual void emitJavaDump( 229 Formatter &out, 230 const std::string &streamName, 231 const std::string &name) const; 232 233 virtual void emitJavaReaderWriter( 234 Formatter &out, 235 const std::string &parcelObj, 236 const std::string &argName, 237 bool isReader) const; 238 239 virtual void emitJavaFieldInitializer( 240 Formatter &out, 241 const std::string &fieldName) const; 242 243 virtual void emitJavaFieldDefaultInitialValue( 244 Formatter &out, 245 const std::string &declaredFieldName) const; 246 247 virtual void emitJavaFieldReaderWriter( 248 Formatter &out, 249 size_t depth, 250 const std::string &parcelName, 251 const std::string &blobName, 252 const std::string &fieldName, 253 const std::string &offset, 254 bool isReader) const; 255 256 virtual void emitHidlDefinition(Formatter& out) const; 257 258 virtual void emitTypeDeclarations(Formatter& out) const; 259 260 virtual void emitGlobalTypeDeclarations(Formatter& out) const; 261 262 // Emit scope C++ forward declaration. 263 // There is no need to forward declare interfaces, as 264 // they are always declared in global scope in dedicated file. 265 virtual void emitTypeForwardDeclaration(Formatter& out) const; 266 267 // Emit any declarations pertaining to this type that have to be 268 // directly in a namespace, i.e. enum class operators. 269 // For android.hardware.foo@1.0::*, this will be in namespace 270 // android::hardware::foo::V1_0 271 virtual void emitPackageTypeDeclarations(Formatter& out) const; 272 273 // Emit any definitions pertaining to this type that have to be 274 // directly in a namespace. Typically, these are things that are only 275 // used for a small subset of types, so by putting them in the header, 276 // the space cost is moved to the small number of clients that use the 277 // feature. 278 // For android.hardware.foo@1.0::*, this will be in namespace 279 // android::hardware::foo::V1_0 280 virtual void emitPackageTypeHeaderDefinitions(Formatter& out) const; 281 282 // Emit any declarations pertaining to this type that have to be 283 // at global scope for transport, e.g. read/writeEmbeddedTo/FromParcel 284 // For android.hardware.foo@1.0::*, this will be in namespace 285 // android::hardware::foo::V1_0 286 virtual void emitPackageHwDeclarations(Formatter& out) const; 287 288 virtual void emitTypeDefinitions(Formatter& out, const std::string& prefix) const; 289 290 virtual void emitJavaTypeDeclarations(Formatter& out, bool atTopLevel) const; 291 292 virtual bool needsEmbeddedReadWrite() const; 293 virtual bool resultNeedsDeref() const; 294 295 // Generates type declaration for vts proto file. 296 // TODO (b/30844146): make it a pure virtual method. 297 virtual void emitVtsTypeDeclarations(Formatter& out) const; 298 // Generates type declaration as attribute of method (return value or method 299 // argument) or attribute of compound type for vts proto file. 300 virtual void emitVtsAttributeType(Formatter& out) const; 301 302 // Returns true iff this type is supported through the Java backend. 303 bool isJavaCompatible() const; 304 bool isJavaCompatible(std::unordered_set<const Type*>* visited) const; 305 virtual bool deepIsJavaCompatible(std::unordered_set<const Type*>* visited) const; 306 // Returns true iff type contains pointer 307 // (excluding methods and inner types). 308 bool containsPointer() const; 309 bool containsPointer(std::unordered_set<const Type*>* visited) const; 310 virtual bool deepContainsPointer(std::unordered_set<const Type*>* visited) const; 311 312 virtual void getAlignmentAndSize(size_t *align, size_t *size) const; 313 314 virtual void appendToExportedTypesVector( 315 std::vector<const Type *> *exportedTypes) const; 316 317 virtual void emitExportedHeader(Formatter& out, bool forJava) const; 318 319 virtual bool isNeverStrongReference() const; 320 321 static void handleError(Formatter &out, ErrorMode mode); 322 protected: 323 void emitReaderWriterEmbeddedForTypeName( 324 Formatter &out, 325 const std::string &name, 326 bool nameIsPointer, 327 const std::string &parcelObj, 328 bool parcelObjIsPointer, 329 bool isReader, 330 ErrorMode mode, 331 const std::string &parentName, 332 const std::string &offsetText, 333 const std::string &typeName, 334 const std::string &childName, 335 const std::string &funcNamespace) const; 336 337 void emitJavaReaderWriterWithSuffix( 338 Formatter &out, 339 const std::string &parcelObj, 340 const std::string &argName, 341 bool isReader, 342 const std::string &suffix, 343 const std::string &extra) const; 344 345 void emitDumpWithMethod( 346 Formatter &out, 347 const std::string &streamName, 348 const std::string &methodName, 349 const std::string &name) const; 350 351 // This is the name given to the type in the hidl file 352 std::string mDefinedName; 353 354 private: 355 ParseStage mParseStage = ParseStage::PARSE; 356 Scope* const mParent; 357 358 DISALLOW_COPY_AND_ASSIGN(Type); 359 }; 360 361 struct TemplatedType : public Type { 362 void setElementType(const Reference<Type>& elementType); 363 const Type* getElementType() const; 364 365 virtual std::string templatedTypeName() const = 0; 366 std::string typeName() const override; 367 368 bool isTemplatedType() const override; 369 370 virtual bool isCompatibleElementType(const Type* elementType) const = 0; 371 372 std::vector<const Reference<Type>*> getReferences() const override; 373 374 virtual status_t validate() const override; 375 376 void emitVtsTypeDeclarations(Formatter& out) const override; 377 void emitVtsAttributeType(Formatter& out) const override; 378 379 protected: 380 TemplatedType(Scope* parent, const std::string& definedName); 381 Reference<Type> mElementType; 382 383 private: 384 DISALLOW_COPY_AND_ASSIGN(TemplatedType); 385 }; 386 387 } // namespace android 388 389 #endif // TYPE_H_ 390 391