1 /* 2 * Copyright (C) 2015, 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 "ast_cpp.h" 18 19 #include <algorithm> 20 21 #include "code_writer.h" 22 #include "logging.h" 23 24 using std::string; 25 using std::unique_ptr; 26 using std::vector; 27 28 namespace android { 29 namespace aidl { 30 namespace cpp { 31 32 ClassDecl::ClassDecl(const std::string& name, const std::string& parent) 33 : name_(name), 34 parent_(parent) {} 35 36 ClassDecl::ClassDecl(const std::string& name, const std::string& parent, 37 std::vector<unique_ptr<Declaration>> public_members, 38 std::vector<unique_ptr<Declaration>> private_members) 39 : name_(name), 40 parent_(parent), 41 public_members_(std::move(public_members)), 42 private_members_(std::move(private_members)) {} 43 44 void ClassDecl::Write(CodeWriter* to) const { 45 to->Write("class %s ", name_.c_str()); 46 47 if (parent_.length() > 0) 48 to->Write(": public %s ", parent_.c_str()); 49 50 to->Write("{\n"); 51 52 if (!public_members_.empty()) 53 to->Write("public:\n"); 54 55 for (const auto& dec : public_members_) 56 dec->Write(to); 57 58 if (!private_members_.empty()) 59 to->Write("private:\n"); 60 61 for (const auto& dec : private_members_) 62 dec->Write(to); 63 64 to->Write("}; // class %s\n", name_.c_str()); 65 } 66 67 void ClassDecl::AddPublic(std::unique_ptr<Declaration> member) { 68 public_members_.push_back(std::move(member)); 69 } 70 71 void ClassDecl::AddPrivate(std::unique_ptr<Declaration> member) { 72 private_members_.push_back(std::move(member)); 73 } 74 75 Enum::EnumField::EnumField(const string& k, const string& v) 76 : key(k), 77 value(v) {} 78 79 Enum::Enum(const string& name, const string& base_type) 80 : enum_name_(name), underlying_type_(base_type) {} 81 82 Enum::Enum(const string& name) : Enum(name, "") {} 83 84 void Enum::Write(CodeWriter* to) const { 85 if (underlying_type_.empty()) { 86 to->Write("enum %s {\n", enum_name_.c_str()); 87 } else { 88 to->Write("enum %s : %s {\n", enum_name_.c_str(), underlying_type_.c_str()); 89 } 90 for (const auto& field : fields_) { 91 if (field.value.empty()) { 92 to->Write(" %s,\n", field.key.c_str()); 93 } else { 94 to->Write(" %s = %s,\n", field.key.c_str(), field.value.c_str()); 95 } 96 } 97 to->Write("};\n"); 98 } 99 100 void Enum::AddValue(const string& key, const string& value) { 101 fields_.emplace_back(key, value); 102 } 103 104 ArgList::ArgList(const std::string& single_argument) 105 : ArgList(vector<string>{single_argument}) {} 106 107 ArgList::ArgList(const std::vector<std::string>& arg_list) { 108 for (const auto& s : arg_list) { 109 arguments_.emplace_back(new LiteralExpression(s)); 110 } 111 } 112 113 ArgList::ArgList(std::vector<std::unique_ptr<AstNode>> arg_list) 114 : arguments_(std::move(arg_list)) {} 115 116 ArgList::ArgList(ArgList&& arg_list) 117 : arguments_(std::move(arg_list.arguments_)) {} 118 119 void ArgList::Write(CodeWriter* to) const { 120 to->Write("("); 121 bool is_first = true; 122 for (const auto& s : arguments_) { 123 if (!is_first) { to->Write(", "); } 124 is_first = false; 125 s->Write(to); 126 } 127 to->Write(")"); 128 } 129 130 ConstructorDecl::ConstructorDecl( 131 const std::string& name, 132 ArgList&& arg_list) 133 : ConstructorDecl(name, std::move(arg_list), 0u) {} 134 135 ConstructorDecl::ConstructorDecl( 136 const std::string& name, 137 ArgList&& arg_list, 138 uint32_t modifiers) 139 : name_(name), 140 arguments_(std::move(arg_list)), 141 modifiers_(modifiers) {} 142 143 void ConstructorDecl::Write(CodeWriter* to) const { 144 if (modifiers_ & Modifiers::IS_VIRTUAL) 145 to->Write("virtual "); 146 147 if (modifiers_ & Modifiers::IS_EXPLICIT) 148 to->Write("explicit "); 149 150 to->Write("%s", name_.c_str()); 151 152 arguments_.Write(to); 153 154 if (modifiers_ & Modifiers::IS_DEFAULT) 155 to->Write(" = default"); 156 157 to->Write(";\n"); 158 } 159 160 MacroDecl::MacroDecl(const std::string& name, ArgList&& arg_list) 161 : name_(name), 162 arguments_(std::move(arg_list)) {} 163 164 void MacroDecl::Write(CodeWriter* to) const { 165 to->Write("%s", name_.c_str()); 166 arguments_.Write(to); 167 to->Write("\n"); 168 } 169 170 MethodDecl::MethodDecl(const std::string& return_type, 171 const std::string& name, 172 ArgList&& arg_list) 173 : MethodDecl(return_type, name, std::move(arg_list), 0u) {} 174 175 MethodDecl::MethodDecl(const std::string& return_type, 176 const std::string& name, 177 ArgList&& arg_list, 178 uint32_t modifiers) 179 : return_type_(return_type), 180 name_(name), 181 arguments_(std::move(arg_list)), 182 is_const_(modifiers & IS_CONST), 183 is_virtual_(modifiers & IS_VIRTUAL), 184 is_override_(modifiers & IS_OVERRIDE), 185 is_pure_virtual_(modifiers & IS_PURE_VIRTUAL), 186 is_static_(modifiers & IS_STATIC) {} 187 188 void MethodDecl::Write(CodeWriter* to) const { 189 if (is_virtual_) 190 to->Write("virtual "); 191 192 if (is_static_) 193 to->Write("static "); 194 195 to->Write("%s %s", return_type_.c_str(), name_.c_str()); 196 197 arguments_.Write(to); 198 199 if (is_const_) 200 to->Write(" const"); 201 202 if (is_override_) 203 to->Write(" override"); 204 205 if (is_pure_virtual_) 206 to->Write(" = 0"); 207 208 to->Write(";\n"); 209 } 210 211 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) { 212 statements_.push_back(std::move(statement)); 213 } 214 215 void StatementBlock::AddStatement(AstNode* statement) { 216 statements_.emplace_back(statement); 217 } 218 219 void StatementBlock::AddLiteral(const std::string& expression_str, 220 bool add_semicolon) { 221 if (add_semicolon) { 222 statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str))); 223 } else { 224 statements_.push_back(unique_ptr<AstNode>( 225 new LiteralExpression(expression_str))); 226 } 227 } 228 229 void StatementBlock::Write(CodeWriter* to) const { 230 to->Write("{\n"); 231 for (const auto& statement : statements_) { 232 statement->Write(to); 233 } 234 to->Write("}\n"); 235 } 236 237 ConstructorImpl::ConstructorImpl(const string& class_name, 238 ArgList&& arg_list, 239 const vector<string>& initializer_list) 240 : class_name_(class_name), 241 arguments_(std::move(arg_list)), 242 initializer_list_(initializer_list) {} 243 244 void ConstructorImpl::Write(CodeWriter* to) const { 245 to->Write("%s::%s", class_name_.c_str(), class_name_.c_str()); 246 arguments_.Write(to); 247 to->Write("\n"); 248 249 bool is_first = true; 250 for (const string& i : initializer_list_) { 251 if (is_first) { 252 to->Write(" : %s", i.c_str()); 253 } else { 254 to->Write(",\n %s", i.c_str()); 255 } 256 is_first = false; 257 } 258 259 body_.Write(to); 260 } 261 262 MethodImpl::MethodImpl(const string& return_type, 263 const string& class_name, 264 const string& method_name, 265 ArgList&& arg_list, 266 bool is_const_method) 267 : return_type_(return_type), 268 method_name_(method_name), 269 arguments_(std::move(arg_list)), 270 is_const_method_(is_const_method) { 271 if (!class_name.empty()) { 272 method_name_ = class_name + "::" + method_name; 273 } 274 } 275 276 StatementBlock* MethodImpl::GetStatementBlock() { 277 return &statements_; 278 } 279 280 void MethodImpl::Write(CodeWriter* to) const { 281 to->Write("%s %s", return_type_.c_str(), method_name_.c_str()); 282 arguments_.Write(to); 283 to->Write("%s ", (is_const_method_) ? " const" : ""); 284 statements_.Write(to); 285 } 286 287 SwitchStatement::SwitchStatement(const std::string& expression) 288 : switch_expression_(expression) {} 289 290 StatementBlock* SwitchStatement::AddCase(const string& value_expression) { 291 auto it = std::find(case_values_.begin(), case_values_.end(), value_expression); 292 if (it != case_values_.end()) { 293 LOG(ERROR) << "internal error: duplicate switch case labels"; 294 return nullptr; 295 } 296 StatementBlock* ret = new StatementBlock(); 297 case_values_.push_back(value_expression); 298 case_logic_.push_back(unique_ptr<StatementBlock>{ret}); 299 return ret; 300 } 301 302 void SwitchStatement::Write(CodeWriter* to) const { 303 to->Write("switch (%s) {\n", switch_expression_.c_str()); 304 for (size_t i = 0; i < case_values_.size(); ++i) { 305 const string& case_value = case_values_[i]; 306 const unique_ptr<StatementBlock>& statements = case_logic_[i]; 307 if (case_value.empty()) { 308 to->Write("default:\n"); 309 } else { 310 to->Write("case %s:\n", case_value.c_str()); 311 } 312 statements->Write(to); 313 to->Write("break;\n"); 314 } 315 to->Write("}\n"); 316 } 317 318 319 Assignment::Assignment(const std::string& left, const std::string& right) 320 : Assignment(left, new LiteralExpression{right}) {} 321 322 Assignment::Assignment(const std::string& left, AstNode* right) 323 : lhs_(left), 324 rhs_(right) {} 325 326 void Assignment::Write(CodeWriter* to) const { 327 to->Write("%s = ", lhs_.c_str()); 328 rhs_->Write(to); 329 to->Write(";\n"); 330 } 331 332 MethodCall::MethodCall(const std::string& method_name, 333 const std::string& single_argument) 334 : MethodCall(method_name, ArgList{single_argument}) {} 335 336 MethodCall::MethodCall(const std::string& method_name, 337 ArgList&& arg_list) 338 : method_name_(method_name), 339 arguments_{std::move(arg_list)} {} 340 341 void MethodCall::Write(CodeWriter* to) const { 342 to->Write("%s", method_name_.c_str()); 343 arguments_.Write(to); 344 } 345 346 IfStatement::IfStatement(AstNode* expression, bool invert_expression) 347 : expression_(expression), 348 invert_expression_(invert_expression) {} 349 350 void IfStatement::Write(CodeWriter* to) const { 351 to->Write("if (%s", (invert_expression_) ? "!(" : ""); 352 expression_->Write(to); 353 to->Write(")%s ", (invert_expression_) ? ")" : ""); 354 on_true_.Write(to); 355 356 if (!on_false_.Empty()) { 357 to->Write("else "); 358 on_false_.Write(to); 359 } 360 } 361 362 Statement::Statement(unique_ptr<AstNode> expression) 363 : expression_(std::move(expression)) {} 364 365 Statement::Statement(AstNode* expression) : expression_(expression) {} 366 367 Statement::Statement(const string& expression) 368 : expression_(new LiteralExpression(expression)) {} 369 370 void Statement::Write(CodeWriter* to) const { 371 expression_->Write(to); 372 to->Write(";\n"); 373 } 374 375 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs) 376 : left_(lhs), 377 right_(rhs), 378 operator_(comparison) {} 379 380 void Comparison::Write(CodeWriter* to) const { 381 to->Write("(("); 382 left_->Write(to); 383 to->Write(") %s (", operator_.c_str()); 384 right_->Write(to); 385 to->Write("))"); 386 } 387 388 LiteralExpression::LiteralExpression(const std::string& expression) 389 : expression_(expression) {} 390 391 void LiteralExpression::Write(CodeWriter* to) const { 392 to->Write("%s", expression_.c_str()); 393 } 394 395 CppNamespace::CppNamespace(const std::string& name, 396 std::vector<unique_ptr<Declaration>> declarations) 397 : declarations_(std::move(declarations)), 398 name_(name) {} 399 400 CppNamespace::CppNamespace(const std::string& name, 401 unique_ptr<Declaration> declaration) 402 : name_(name) { 403 declarations_.push_back(std::move(declaration)); 404 } 405 CppNamespace::CppNamespace(const std::string& name) 406 : name_(name) {} 407 408 void CppNamespace::Write(CodeWriter* to) const { 409 to->Write("namespace %s {\n\n", name_.c_str()); 410 411 for (const auto& dec : declarations_) { 412 dec->Write(to); 413 to->Write("\n"); 414 } 415 416 to->Write("} // namespace %s\n", name_.c_str()); 417 } 418 419 Document::Document(const std::vector<std::string>& include_list, 420 unique_ptr<CppNamespace> a_namespace) 421 : include_list_(include_list), 422 namespace_(std::move(a_namespace)) {} 423 424 void Document::Write(CodeWriter* to) const { 425 for (const auto& include : include_list_) { 426 to->Write("#include <%s>\n", include.c_str()); 427 } 428 to->Write("\n"); 429 430 namespace_->Write(to); 431 } 432 433 CppHeader::CppHeader(const std::string& include_guard, 434 const std::vector<std::string>& include_list, 435 unique_ptr<CppNamespace> a_namespace) 436 : Document(include_list, std::move(a_namespace)), 437 include_guard_(include_guard) {} 438 439 void CppHeader::Write(CodeWriter* to) const { 440 to->Write("#ifndef %s\n", include_guard_.c_str()); 441 to->Write("#define %s\n\n", include_guard_.c_str()); 442 443 Document::Write(to); 444 to->Write("\n"); 445 446 to->Write("#endif // %s\n", include_guard_.c_str()); 447 } 448 449 CppSource::CppSource(const std::vector<std::string>& include_list, 450 unique_ptr<CppNamespace> a_namespace) 451 : Document(include_list, std::move(a_namespace)) {} 452 453 } // namespace cpp 454 } // namespace aidl 455 } // namespace android 456