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 #include "CompositeDeclaration.h" 18 #include "FunctionDeclaration.h" 19 #include "VarDeclaration.h" 20 #include "Declaration.h" 21 22 #include <algorithm> 23 #include <iostream> 24 #include <string> 25 26 namespace android { 27 28 CompositeDeclaration::CompositeDeclaration( 29 const Type::Qualifier::Qualification qualifier, 30 const std::string &name, 31 std::vector<android::Declaration *> *fieldDeclarations) 32 : Declaration(""), 33 mQualifier(qualifier), 34 mFieldDeclarations(fieldDeclarations) 35 { 36 setName(name); 37 } 38 39 CompositeDeclaration::~CompositeDeclaration() { 40 if(mFieldDeclarations != NULL) { 41 for(auto* decl : *mFieldDeclarations) { 42 delete decl; 43 } 44 } 45 delete mFieldDeclarations; 46 } 47 48 void CompositeDeclaration::setName(const std::string &name) { 49 Declaration::setName(name); 50 forcePascalCase(); 51 } 52 53 const Type::Qualifier::Qualification &CompositeDeclaration::getQualifier() const { 54 return mQualifier; 55 } 56 const std::vector<android::Declaration *>* 57 CompositeDeclaration::getFieldDeclarations() const { 58 return mFieldDeclarations; 59 } 60 61 void CompositeDeclaration::generateInterface(Formatter &out) const { 62 generateCommentText(out); 63 out << "interface " << getInterfaceName() << " {\n\n"; 64 65 generateBody(out); 66 67 out << "};\n"; 68 } 69 70 void CompositeDeclaration::generateSource(Formatter &out) const { 71 CHECK(mQualifier == Type::Qualifier::STRUCT || 72 mQualifier == Type::Qualifier::UNION || 73 mQualifier == Type::Qualifier::ENUM); 74 75 out << Type::qualifierText(mQualifier) << " " << getName(); 76 77 if (mQualifier == Type::Qualifier::ENUM) { 78 out << " : "; 79 80 if (mEnumTypeName.empty()) { 81 out << "int32_t /* NOTE: type is guessed */"; 82 } else { 83 out << mEnumTypeName; 84 } 85 86 } 87 88 out << " {\n"; 89 90 generateBody(out); 91 92 out << "};\n"; 93 } 94 95 void CompositeDeclaration::generateBody(Formatter &out) const { 96 out.indent(); 97 98 for (auto *declaration : *mFieldDeclarations) { 99 declaration->generateCommentText(out); 100 declaration->generateSource(out); 101 out << "\n"; 102 } 103 104 out.unindent(); 105 } 106 107 void CompositeDeclaration::processContents(AST &ast) { 108 for (auto &declaration : *mFieldDeclarations) { 109 declaration->processContents(ast); 110 } 111 112 if (isInterface()) { 113 // move non function fields into a containing struct 114 115 auto nonFpDecs = new std::vector<Declaration*>; 116 117 auto it = mFieldDeclarations->begin(); 118 while (it != mFieldDeclarations->end()) { 119 if((*it)->decType() != FunctionDeclaration::type()) { 120 bool keep = true; 121 if((*it)->decType() == VarDeclaration::type()) { 122 VarDeclaration* var = (VarDeclaration *)(*it); 123 // Conventional HALs were all required to have 124 // a member of this type. 125 // This member is no longer needed for HIDL 126 if(var->getType()->isHwDevice()) { 127 keep = false; 128 } 129 } 130 131 if (keep) { 132 nonFpDecs->push_back(*it); 133 } 134 it = mFieldDeclarations->erase(it); 135 } else { 136 it++; 137 } 138 } 139 140 if (!nonFpDecs->empty()) { 141 auto subStruct = new CompositeDeclaration(Type::Qualifier::STRUCT, 142 getName(), 143 nonFpDecs); 144 145 mFieldDeclarations->insert(mFieldDeclarations->begin(), subStruct); 146 } 147 } 148 } 149 150 std::string CompositeDeclaration::getInterfaceName() const { 151 return "I" + getName(); 152 } 153 154 bool CompositeDeclaration::isInterface() const { 155 if (mQualifier != Type::Qualifier::STRUCT) { 156 return false; 157 } 158 159 for (auto &declaration : *mFieldDeclarations) { 160 if (declaration->decType() == FunctionDeclaration::type()) { 161 return true; 162 } 163 } 164 return false; 165 } 166 167 void CompositeDeclaration::setEnumTypeName(const std::string &name) { 168 CHECK(mQualifier == Type::Qualifier::ENUM); 169 170 mEnumTypeName = name; 171 } 172 173 } //namespace android 174