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 AST_H_ 18 19 #define AST_H_ 20 21 #include <android-base/macros.h> 22 #include <hidl-hash/Hash.h> 23 #include <hidl-util/FQName.h> 24 #include <functional> 25 #include <map> 26 #include <set> 27 #include <string> 28 #include <vector> 29 30 #include "Scope.h" 31 #include "Type.h" 32 33 namespace android { 34 35 struct Coordinator; 36 struct ConstantExpression; 37 struct EnumValue; 38 struct Formatter; 39 struct Interface; 40 struct Location; 41 struct Method; 42 struct NamedType; 43 template <class T> 44 struct NamedReference; 45 struct Type; 46 47 struct AST { 48 AST(const Coordinator* coordinator, const Hash* fileHash); 49 50 bool setPackage(const char *package); 51 bool addImport(const char *import); 52 53 // package and version really. 54 FQName package() const; 55 bool isInterface() const; 56 bool definesInterfaces() const; 57 58 // Adds package, version and scope stack to local name 59 FQName makeFullName(const char* localName, Scope* scope) const; 60 61 void addScopedType(NamedType* type, Scope* scope); 62 63 const std::string& getFilename() const; 64 const Hash* getFileHash() const; 65 66 // Look up local identifier. 67 // It could be plain identifier or enum value as described by lookupEnumValue. 68 LocalIdentifier* lookupLocalIdentifier(const Reference<LocalIdentifier>& ref, Scope* scope); 69 70 // Look up an enum value by "FQName:valueName". 71 EnumValue* lookupEnumValue(const FQName& fqName, std::string* errorMsg, Scope* scope); 72 73 // Look up a type by FQName, "pure" names, i.e. those without package 74 // or version are first looked up in the current scope chain. 75 // After that lookup proceeds to imports. 76 Type* lookupType(const FQName& fqName, Scope* scope); 77 78 void addImportedAST(AST *ast); 79 80 // Calls all passes after parsing required before 81 // being ready to generate output. 82 status_t postParse(); 83 84 // Recursive pass on constant expression tree 85 status_t constantExpressionRecursivePass( 86 const std::function<status_t(ConstantExpression*)>& func, bool processBeforeDependencies); 87 status_t constantExpressionRecursivePass( 88 const std::function<status_t(const ConstantExpression*)>& func, 89 bool processBeforeDependencies) const; 90 91 // Recursive tree pass that sets ParseStage of all types to newStage. 92 status_t setParseStage(Type::ParseStage oldStage, Type::ParseStage newStage); 93 94 // Recursive tree pass that looks up all referenced types 95 status_t lookupTypes(); 96 97 // Recursive tree pass that looks up all referenced local identifiers 98 // and types referenced by constant expressions 99 status_t lookupConstantExpressions(); 100 101 // Recursive tree pass that validates that all defined types 102 // have unique names in their scopes. 103 status_t validateDefinedTypesUniqueNames() const; 104 105 // Recursive tree pass that completes type declarations 106 // that depend on super types 107 status_t resolveInheritance(); 108 109 // Recursive tree pass that validates constant expressions 110 status_t validateConstantExpressions() const; 111 112 // Recursive tree pass that evaluates constant expressions 113 status_t evaluateConstantExpressions(); 114 115 // Recursive tree pass that validates all type-related 116 // syntax restrictions 117 status_t validate() const; 118 119 // Recursive tree pass that ensures that type definitions and references 120 // are acyclic and reorderes type definitions in reversed topological order. 121 status_t topologicalReorder(); 122 123 // Recursive tree pass that ensures that constant expressions 124 // are acyclic. 125 status_t checkAcyclicConstantExpressions() const; 126 127 // Recursive tree pass that checks C++ forward declaration restrictions. 128 status_t checkForwardReferenceRestrictions() const; 129 130 status_t gatherReferencedTypes(); 131 132 void generateCppSource(Formatter& out) const; 133 134 void generateInterfaceHeader(Formatter& out) const; 135 void generateHwBinderHeader(Formatter& out) const; 136 void generateStubHeader(Formatter& out) const; 137 void generateProxyHeader(Formatter& out) const; 138 void generatePassthroughHeader(Formatter& out) const; 139 140 void generateCppImplHeader(Formatter& out) const; 141 void generateCppImplSource(Formatter& out) const; 142 143 void generateCppAdapterHeader(Formatter& out) const; 144 void generateCppAdapterSource(Formatter& out) const; 145 146 void generateJava(Formatter& out, const std::string& limitToType) const; 147 void generateJavaTypes(Formatter& out, const std::string& limitToType) const; 148 149 void generateVts(Formatter& out) const; 150 151 void generateDependencies(Formatter& out) const; 152 153 void getImportedPackages(std::set<FQName> *importSet) const; 154 155 // Run getImportedPackages on this, then run getImportedPackages on 156 // each AST in each package referenced in importSet. 157 void getImportedPackagesHierarchy(std::set<FQName> *importSet) const; 158 159 bool isJavaCompatible() const; 160 161 // Warning: this only includes names explicitly referenced in code. 162 // It does not include all names which are imported. 163 // 164 // Currently, there is one valid usecase for this: importing exactly 165 // the names which need to be imported in generated code. If you import 166 // based on getAllImportedNamesGranular instead, you will import things 167 // that aren't actually used in the resultant code. 168 // 169 // Get transitive closure of imported interface/types. This will add 170 // everything exported by a package even if only a single type from 171 // that package was explicitly imported! 172 void getAllImportedNames(std::set<FQName> *allImportSet) const; 173 174 // Get imported types, this includes those explicitly imported as well 175 // as all types defined in imported packages. 176 void getAllImportedNamesGranular(std::set<FQName> *allImportSet) const; 177 178 void appendToExportedTypesVector( 179 std::vector<const Type *> *exportedTypes) const; 180 181 // used by the parser. 182 void addSyntaxError(); 183 size_t syntaxErrors() const; 184 185 bool isIBase() const; 186 187 // or nullptr if not isInterface 188 const Interface *getInterface() const; 189 190 // types or Interface base name (e.x. Foo) 191 std::string getBaseName() const; 192 193 Scope* getRootScope(); 194 195 static void generateCppPackageInclude(Formatter& out, const FQName& package, 196 const std::string& klass); 197 198 void addDefinedTypes(std::set<FQName> *definedTypes) const; 199 void addReferencedTypes(std::set<FQName> *referencedTypes) const; 200 201 void addToImportedNamesGranular(const FQName &fqName); 202 203 private: 204 const Coordinator* mCoordinator; 205 const Hash* mFileHash; 206 207 RootScope mRootScope; 208 209 FQName mPackage; 210 211 // A set of all external interfaces/types that are _actually_ referenced 212 // in this AST, this is a subset of those specified in import statements. 213 // Note that this set only resolves to the granularity of either an 214 // interface type or a whole package. 215 std::set<FQName> mImportedNames; 216 217 // This is the set of actually imported types. 218 std::set<FQName> mImportedNamesGranular; 219 220 // Warning: this only includes names explicitly referenced in code. 221 // It does not include all names which are imported. 222 // 223 // A set of all ASTs we explicitly or implicitly (types.hal) import. 224 std::set<AST *> mImportedASTs; 225 226 // If a single type (instead of the whole AST) is imported, the AST will be 227 // present as a key to this map, with the value being a list of types 228 // imported from this AST. If an AST appears in mImportedASTs but not in 229 // mImportedTypes, then the whole AST is imported. 230 std::map<AST *, std::set<Type *>> mImportedTypes; 231 232 // Types keyed by full names defined in this AST. 233 std::map<FQName, Type *> mDefinedTypesByFullName; 234 235 // used by the parser. 236 size_t mSyntaxErrors = 0; 237 238 std::set<FQName> mReferencedTypeNames; 239 240 // Helper functions for lookupType. 241 Type* lookupTypeLocally(const FQName& fqName, Scope* scope); 242 status_t lookupAutofilledType(const FQName &fqName, Type **returnedType); 243 Type *lookupTypeFromImports(const FQName &fqName); 244 245 // Find a type matching fqName (which may be partial) and if found 246 // return the associated type and fill in the full "matchingName". 247 // Only types defined in this very AST are considered. 248 Type *findDefinedType(const FQName &fqName, FQName *matchingName) const; 249 250 void getPackageComponents(std::vector<std::string> *components) const; 251 252 void getPackageAndVersionComponents( 253 std::vector<std::string> *components, bool cpp_compatible) const; 254 255 std::string makeHeaderGuard(const std::string &baseName, 256 bool indicateGenerated = true) const; 257 void enterLeaveNamespace(Formatter &out, bool enter) const; 258 259 static void generateCheckNonNull(Formatter &out, const std::string &nonNull); 260 261 void generateTypeSource(Formatter& out, const std::string& ifaceName) const; 262 263 // a method, and in which interface is it originally defined. 264 // be careful of the case where method.isHidlReserved(), where interface 265 // is effectively useless. 266 using MethodGenerator = std::function<void(const Method*, const Interface*)>; 267 268 void generateTemplatizationLink(Formatter& out) const; 269 void generateCppTag(Formatter& out, const std::string& tag) const; 270 271 void generateMethods(Formatter& out, const MethodGenerator& gen, 272 bool includeParents = true) const; 273 void generateStubImplMethod(Formatter& out, const std::string& className, 274 const Method* method) const; 275 void generatePassthroughMethod(Formatter& out, const Method* method, const Interface* superInterface) const; 276 void generateStaticProxyMethodSource(Formatter& out, const std::string& className, 277 const Method* method, const Interface* superInterface) const; 278 void generateProxyMethodSource(Formatter& out, const std::string& className, 279 const Method* method, const Interface* superInterface) const; 280 void generateAdapterMethod(Formatter& out, const Method* method) const; 281 282 void generateFetchSymbol(Formatter &out, const std::string &ifaceName) const; 283 284 void generateProxySource(Formatter& out, const FQName& fqName) const; 285 286 void generateStubSource(Formatter& out, const Interface* iface) const; 287 288 void generateStubSourceForMethod(Formatter& out, const Method* method, 289 const Interface* superInterface) const; 290 void generateStaticStubMethodSource(Formatter& out, const FQName& fqName, 291 const Method* method, const Interface* superInterface) const; 292 293 void generatePassthroughSource(Formatter& out) const; 294 295 void generateInterfaceSource(Formatter& out) const; 296 297 enum InstrumentationEvent { 298 SERVER_API_ENTRY = 0, 299 SERVER_API_EXIT, 300 CLIENT_API_ENTRY, 301 CLIENT_API_EXIT, 302 SYNC_CALLBACK_ENTRY, 303 SYNC_CALLBACK_EXIT, 304 ASYNC_CALLBACK_ENTRY, 305 ASYNC_CALLBACK_EXIT, 306 PASSTHROUGH_ENTRY, 307 PASSTHROUGH_EXIT, 308 }; 309 310 void generateCppAtraceCall( 311 Formatter &out, 312 InstrumentationEvent event, 313 const Method *method) const; 314 315 void generateCppInstrumentationCall( 316 Formatter &out, 317 InstrumentationEvent event, 318 const Method *method, 319 const Interface* superInterface) const; 320 321 void declareCppReaderLocals(Formatter& out, const std::vector<NamedReference<Type>*>& arg, 322 bool forResults) const; 323 324 void emitCppReaderWriter(Formatter& out, const std::string& parcelObj, bool parcelObjIsPointer, 325 const NamedReference<Type>* arg, bool isReader, Type::ErrorMode mode, 326 bool addPrefixToName) const; 327 328 void emitCppResolveReferences(Formatter& out, const std::string& parcelObj, 329 bool parcelObjIsPointer, const NamedReference<Type>* arg, 330 bool isReader, Type::ErrorMode mode, bool addPrefixToName) const; 331 332 void emitJavaReaderWriter(Formatter& out, const std::string& parcelObj, 333 const NamedReference<Type>* arg, bool isReader, 334 bool addPrefixToName) const; 335 336 void emitVtsTypeDeclarations(Formatter& out) const; 337 338 DISALLOW_COPY_AND_ASSIGN(AST); 339 }; 340 341 } // namespace android 342 343 #endif // AST_H_ 344