1 /* 2 * Copyright 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 "ProfilerCodeGenBase.h" 18 #include "utils/InterfaceSpecUtil.h" 19 #include "utils/StringUtil.h" 20 #include "VtsCompilerUtils.h" 21 22 namespace android { 23 namespace vts { 24 25 void ProfilerCodeGenBase::GenerateAll( 26 Formatter& header_out, Formatter& source_out, 27 const ComponentSpecificationMessage& message) { 28 GenerateHeaderFile(header_out, message); 29 GenerateSourceFile(source_out, message); 30 } 31 32 void ProfilerCodeGenBase::GenerateHeaderFile( 33 Formatter& out, const ComponentSpecificationMessage& message) { 34 FQName component_fq_name = GetFQName(message); 35 out << "#ifndef __VTS_PROFILER_" << component_fq_name.tokenName() 36 << "__\n"; 37 out << "#define __VTS_PROFILER_" << component_fq_name.tokenName() 38 << "__\n"; 39 out << "\n\n"; 40 GenerateHeaderIncludeFiles(out, message); 41 GenerateUsingDeclaration(out, message); 42 GenerateOpenNameSpaces(out, message); 43 44 if (message.has_interface()) { 45 InterfaceSpecificationMessage interface = message.interface(); 46 // First generate the declaration of profiler functions for all user 47 // defined types within the interface. 48 for (const auto attribute : interface.attribute()) { 49 GenerateProfilerMethodDeclForAttribute(out, attribute); 50 } 51 52 out << "extern \"C\" {\n"; 53 out.indent(); 54 55 // Generate the declaration of main profiler function. 56 FQName component_fq_name = GetFQName(message); 57 out << "\nvoid HIDL_INSTRUMENTATION_FUNCTION_" << component_fq_name.tokenName() 58 << "(\n"; 59 out.indent(); 60 out.indent(); 61 out << "details::HidlInstrumentor::InstrumentationEvent event,\n"; 62 out << "const char* package,\n"; 63 out << "const char* version,\n"; 64 out << "const char* interface,\n"; 65 out << "const char* method,\n"; 66 out << "std::vector<void *> *args);\n"; 67 out.unindent(); 68 out.unindent(); 69 70 out.unindent(); 71 out << "}\n\n"; 72 } else { 73 // For types.vts, just generate the declaration of profiler functions 74 // for all user defined types. 75 for (const auto attribute : message.attribute()) { 76 GenerateProfilerMethodDeclForAttribute(out, attribute); 77 } 78 } 79 80 GenerateCloseNameSpaces(out, message); 81 out << "#endif\n"; 82 } 83 84 void ProfilerCodeGenBase::GenerateSourceFile( 85 Formatter& out, const ComponentSpecificationMessage& message) { 86 GenerateSourceIncludeFiles(out, message); 87 GenerateUsingDeclaration(out, message); 88 GenerateMacros(out, message); 89 GenerateOpenNameSpaces(out, message); 90 91 if (message.has_interface()) { 92 InterfaceSpecificationMessage interface = message.interface(); 93 // First generate profiler functions for all user defined types within 94 // the interface. 95 for (const auto attribute : interface.attribute()) { 96 GenerateProfilerMethodImplForAttribute(out, attribute); 97 } 98 // Generate the main profiler function. 99 FQName component_fq_name = GetFQName(message); 100 out << "\nvoid HIDL_INSTRUMENTATION_FUNCTION_" << component_fq_name.tokenName() 101 << "(\n"; 102 out.indent(); 103 out.indent(); 104 out << "details::HidlInstrumentor::InstrumentationEvent event " 105 "__attribute__((__unused__)),\n"; 106 out << "const char* package,\n"; 107 out << "const char* version,\n"; 108 out << "const char* interface,\n"; 109 out << "const char* method __attribute__((__unused__)),\n"; 110 out << "std::vector<void *> *args __attribute__((__unused__))) {\n"; 111 out.unindent(); 112 113 // Generate code for sanity check. 114 GenerateProfilerSanityCheck(out, message); 115 116 if (interface.api_size() > 0) { 117 // Generate code to define local variables. 118 GenerateLocalVariableDefinition(out, message); 119 120 // Generate the profiler code for each method. 121 for (const FunctionSpecificationMessage api : interface.api()) { 122 out << "if (strcmp(method, \"" << api.name() << "\") == 0) {\n"; 123 out.indent(); 124 GenerateProfilerForMethod(out, api); 125 out.unindent(); 126 out << "}\n"; 127 } 128 } 129 130 out.unindent(); 131 out << "}\n\n"; 132 } else { 133 // For types.vts, just generate profiler functions for the user defined 134 // types. 135 for (const auto attribute : message.attribute()) { 136 GenerateProfilerMethodImplForAttribute(out, attribute); 137 } 138 } 139 140 GenerateCloseNameSpaces(out, message); 141 } 142 143 void ProfilerCodeGenBase::GenerateProfilerForTypedVariable(Formatter& out, 144 const VariableSpecificationMessage& val, const std::string& arg_name, 145 const std::string& arg_value) { 146 switch (val.type()) { 147 case TYPE_SCALAR: 148 { 149 GenerateProfilerForScalarVariable(out, val, arg_name, arg_value); 150 break; 151 } 152 case TYPE_STRING: 153 { 154 GenerateProfilerForStringVariable(out, val, arg_name, arg_value); 155 break; 156 } 157 case TYPE_ENUM: 158 { 159 GenerateProfilerForEnumVariable(out, val, arg_name, arg_value); 160 break; 161 } 162 case TYPE_VECTOR: 163 { 164 GenerateProfilerForVectorVariable(out, val, arg_name, arg_value); 165 break; 166 } 167 case TYPE_ARRAY: 168 { 169 GenerateProfilerForArrayVariable(out, val, arg_name, arg_value); 170 break; 171 } 172 case TYPE_STRUCT: 173 { 174 GenerateProfilerForStructVariable(out, val, arg_name, arg_value); 175 break; 176 } 177 case TYPE_UNION: { 178 GenerateProfilerForUnionVariable(out, val, arg_name, arg_value); 179 break; 180 } 181 case TYPE_HIDL_CALLBACK: 182 { 183 GenerateProfilerForHidlCallbackVariable(out, val, arg_name, arg_value); 184 break; 185 } 186 case TYPE_HIDL_INTERFACE: 187 { 188 GenerateProfilerForHidlInterfaceVariable(out, val, arg_name, arg_value); 189 break; 190 } 191 case TYPE_MASK: 192 { 193 GenerateProfilerForMaskVariable(out, val, arg_name, arg_value); 194 break; 195 } 196 case TYPE_HANDLE: { 197 GenerateProfilerForHandleVariable(out, val, arg_name, arg_value); 198 break; 199 } 200 case TYPE_HIDL_MEMORY: 201 { 202 GenerateProfilerForHidlMemoryVariable(out, val, arg_name, arg_value); 203 break; 204 } 205 case TYPE_POINTER: 206 { 207 GenerateProfilerForPointerVariable(out, val, arg_name, arg_value); 208 break; 209 } 210 case TYPE_FMQ_SYNC: 211 { 212 GenerateProfilerForFMQSyncVariable(out, val, arg_name, arg_value); 213 break; 214 } 215 case TYPE_FMQ_UNSYNC: 216 { 217 GenerateProfilerForFMQUnsyncVariable(out, val, arg_name, arg_value); 218 break; 219 } 220 default: 221 { 222 cout << "not supported.\n"; 223 } 224 } 225 } 226 227 void ProfilerCodeGenBase::GenerateProfilerMethodDeclForAttribute(Formatter& out, 228 const VariableSpecificationMessage& attribute) { 229 if (attribute.type() == TYPE_STRUCT || attribute.type() == TYPE_UNION) { 230 // Recursively generate profiler method declaration for all sub_types. 231 for (const auto sub_struct : attribute.sub_struct()) { 232 GenerateProfilerMethodDeclForAttribute(out, sub_struct); 233 } 234 for (const auto sub_union : attribute.sub_union()) { 235 GenerateProfilerMethodDeclForAttribute(out, sub_union); 236 } 237 } 238 std::string attribute_name = attribute.name(); 239 ReplaceSubString(attribute_name, "::", "__"); 240 out << "void profile__" << attribute_name 241 << "(VariableSpecificationMessage* arg_name,\n" << attribute.name() 242 << " arg_val_name);\n"; 243 } 244 245 void ProfilerCodeGenBase::GenerateProfilerMethodImplForAttribute( 246 Formatter& out, const VariableSpecificationMessage& attribute) { 247 if (attribute.type() == TYPE_STRUCT || attribute.type() == TYPE_UNION) { 248 // Recursively generate profiler method implementation for all sub_types. 249 for (const auto sub_struct : attribute.sub_struct()) { 250 GenerateProfilerMethodImplForAttribute(out, sub_struct); 251 } 252 for (const auto sub_union : attribute.sub_union()) { 253 GenerateProfilerMethodImplForAttribute(out, sub_union); 254 } 255 } 256 std::string attribute_name = attribute.name(); 257 ReplaceSubString(attribute_name, "::", "__"); 258 out << "void profile__" << attribute_name 259 << "(VariableSpecificationMessage* arg_name,\n" 260 << attribute.name() << " arg_val_name __attribute__((__unused__))) {\n"; 261 out.indent(); 262 GenerateProfilerForTypedVariable(out, attribute, "arg_name", "arg_val_name"); 263 out.unindent(); 264 out << "}\n\n"; 265 } 266 267 void ProfilerCodeGenBase::GenerateOpenNameSpaces(Formatter& out, 268 const ComponentSpecificationMessage& /*message*/) { 269 out << "namespace android {\n"; 270 out << "namespace vts {\n"; 271 } 272 273 void ProfilerCodeGenBase::GenerateCloseNameSpaces(Formatter& out, 274 const ComponentSpecificationMessage& /*message*/) { 275 out << "} // namespace vts\n"; 276 out << "} // namespace android\n"; 277 } 278 279 } // namespace vts 280 } // namespace android 281