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