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 MethodDecl::MethodDecl(const std::string& return_type, 161 const std::string& name, 162 ArgList&& arg_list) 163 : MethodDecl(return_type, name, std::move(arg_list), 0u) {} 164 165 MethodDecl::MethodDecl(const std::string& return_type, 166 const std::string& name, 167 ArgList&& arg_list, 168 uint32_t modifiers) 169 : return_type_(return_type), 170 name_(name), 171 arguments_(std::move(arg_list)), 172 is_const_(modifiers & IS_CONST), 173 is_virtual_(modifiers & IS_VIRTUAL), 174 is_override_(modifiers & IS_OVERRIDE), 175 is_pure_virtual_(modifiers & IS_PURE_VIRTUAL) {} 176 177 void MethodDecl::Write(CodeWriter* to) const { 178 if (is_virtual_) 179 to->Write("virtual "); 180 181 to->Write("%s %s", return_type_.c_str(), name_.c_str()); 182 183 arguments_.Write(to); 184 185 if (is_const_) 186 to->Write(" const"); 187 188 if (is_override_) 189 to->Write(" override"); 190 191 if (is_pure_virtual_) 192 to->Write(" = 0"); 193 194 to->Write(";\n"); 195 } 196 197 void StatementBlock::AddStatement(unique_ptr<AstNode> statement) { 198 statements_.push_back(std::move(statement)); 199 } 200 201 void StatementBlock::AddStatement(AstNode* statement) { 202 statements_.emplace_back(statement); 203 } 204 205 void StatementBlock::AddLiteral(const std::string& expression_str, 206 bool add_semicolon) { 207 if (add_semicolon) { 208 statements_.push_back(unique_ptr<AstNode>(new Statement(expression_str))); 209 } else { 210 statements_.push_back(unique_ptr<AstNode>( 211 new LiteralExpression(expression_str))); 212 } 213 } 214 215 void StatementBlock::Write(CodeWriter* to) const { 216 to->Write("{\n"); 217 for (const auto& statement : statements_) { 218 statement->Write(to); 219 } 220 to->Write("}\n"); 221 } 222 223 ConstructorImpl::ConstructorImpl(const string& class_name, 224 ArgList&& arg_list, 225 const vector<string>& initializer_list) 226 : class_name_(class_name), 227 arguments_(std::move(arg_list)), 228 initializer_list_(initializer_list) {} 229 230 void ConstructorImpl::Write(CodeWriter* to) const { 231 to->Write("%s::%s", class_name_.c_str(), class_name_.c_str()); 232 arguments_.Write(to); 233 to->Write("\n"); 234 235 bool is_first = true; 236 for (const string& i : initializer_list_) { 237 if (is_first) { 238 to->Write(" : %s", i.c_str()); 239 } else { 240 to->Write(",\n %s", i.c_str()); 241 } 242 is_first = false; 243 } 244 245 body_.Write(to); 246 } 247 248 MethodImpl::MethodImpl(const string& return_type, 249 const string& class_name, 250 const string& method_name, 251 ArgList&& arg_list, 252 bool is_const_method) 253 : return_type_(return_type), 254 method_name_(method_name), 255 arguments_(std::move(arg_list)), 256 is_const_method_(is_const_method) { 257 if (!class_name.empty()) { 258 method_name_ = class_name + "::" + method_name; 259 } 260 } 261 262 StatementBlock* MethodImpl::GetStatementBlock() { 263 return &statements_; 264 } 265 266 void MethodImpl::Write(CodeWriter* to) const { 267 to->Write("%s %s", return_type_.c_str(), method_name_.c_str()); 268 arguments_.Write(to); 269 to->Write("%s ", (is_const_method_) ? " const" : ""); 270 statements_.Write(to); 271 } 272 273 SwitchStatement::SwitchStatement(const std::string& expression) 274 : switch_expression_(expression) {} 275 276 StatementBlock* SwitchStatement::AddCase(const string& value_expression) { 277 auto it = std::find(case_values_.begin(), case_values_.end(), value_expression); 278 if (it != case_values_.end()) { 279 LOG(ERROR) << "internal error: duplicate switch case labels"; 280 return nullptr; 281 } 282 StatementBlock* ret = new StatementBlock(); 283 case_values_.push_back(value_expression); 284 case_logic_.push_back(unique_ptr<StatementBlock>{ret}); 285 return ret; 286 } 287 288 void SwitchStatement::Write(CodeWriter* to) const { 289 to->Write("switch (%s) {\n", switch_expression_.c_str()); 290 for (size_t i = 0; i < case_values_.size(); ++i) { 291 const string& case_value = case_values_[i]; 292 const unique_ptr<StatementBlock>& statements = case_logic_[i]; 293 if (case_value.empty()) { 294 to->Write("default:\n"); 295 } else { 296 to->Write("case %s:\n", case_value.c_str()); 297 } 298 statements->Write(to); 299 to->Write("break;\n"); 300 } 301 to->Write("}\n"); 302 } 303 304 305 Assignment::Assignment(const std::string& left, const std::string& right) 306 : Assignment(left, new LiteralExpression{right}) {} 307 308 Assignment::Assignment(const std::string& left, AstNode* right) 309 : lhs_(left), 310 rhs_(right) {} 311 312 void Assignment::Write(CodeWriter* to) const { 313 to->Write("%s = ", lhs_.c_str()); 314 rhs_->Write(to); 315 to->Write(";\n"); 316 } 317 318 MethodCall::MethodCall(const std::string& method_name, 319 const std::string& single_argument) 320 : MethodCall(method_name, ArgList{single_argument}) {} 321 322 MethodCall::MethodCall(const std::string& method_name, 323 ArgList&& arg_list) 324 : method_name_(method_name), 325 arguments_{std::move(arg_list)} {} 326 327 void MethodCall::Write(CodeWriter* to) const { 328 to->Write("%s", method_name_.c_str()); 329 arguments_.Write(to); 330 } 331 332 IfStatement::IfStatement(AstNode* expression, bool invert_expression) 333 : expression_(expression), 334 invert_expression_(invert_expression) {} 335 336 void IfStatement::Write(CodeWriter* to) const { 337 to->Write("if (%s", (invert_expression_) ? "!(" : ""); 338 expression_->Write(to); 339 to->Write(")%s ", (invert_expression_) ? ")" : ""); 340 on_true_.Write(to); 341 342 if (!on_false_.Empty()) { 343 to->Write("else "); 344 on_false_.Write(to); 345 } 346 } 347 348 Statement::Statement(unique_ptr<AstNode> expression) 349 : expression_(std::move(expression)) {} 350 351 Statement::Statement(AstNode* expression) : expression_(expression) {} 352 353 Statement::Statement(const string& expression) 354 : expression_(new LiteralExpression(expression)) {} 355 356 void Statement::Write(CodeWriter* to) const { 357 expression_->Write(to); 358 to->Write(";\n"); 359 } 360 361 Comparison::Comparison(AstNode* lhs, const string& comparison, AstNode* rhs) 362 : left_(lhs), 363 right_(rhs), 364 operator_(comparison) {} 365 366 void Comparison::Write(CodeWriter* to) const { 367 to->Write("(("); 368 left_->Write(to); 369 to->Write(") %s (", operator_.c_str()); 370 right_->Write(to); 371 to->Write("))"); 372 } 373 374 LiteralExpression::LiteralExpression(const std::string& expression) 375 : expression_(expression) {} 376 377 void LiteralExpression::Write(CodeWriter* to) const { 378 to->Write("%s", expression_.c_str()); 379 } 380 381 CppNamespace::CppNamespace(const std::string& name, 382 std::vector<unique_ptr<Declaration>> declarations) 383 : declarations_(std::move(declarations)), 384 name_(name) {} 385 386 CppNamespace::CppNamespace(const std::string& name, 387 unique_ptr<Declaration> declaration) 388 : name_(name) { 389 declarations_.push_back(std::move(declaration)); 390 } 391 CppNamespace::CppNamespace(const std::string& name) 392 : name_(name) {} 393 394 void CppNamespace::Write(CodeWriter* to) const { 395 to->Write("namespace %s {\n\n", name_.c_str()); 396 397 for (const auto& dec : declarations_) { 398 dec->Write(to); 399 to->Write("\n"); 400 } 401 402 to->Write("} // namespace %s\n", name_.c_str()); 403 } 404 405 Document::Document(const std::vector<std::string>& include_list, 406 unique_ptr<CppNamespace> a_namespace) 407 : include_list_(include_list), 408 namespace_(std::move(a_namespace)) {} 409 410 void Document::Write(CodeWriter* to) const { 411 for (const auto& include : include_list_) { 412 to->Write("#include <%s>\n", include.c_str()); 413 } 414 to->Write("\n"); 415 416 namespace_->Write(to); 417 } 418 419 CppHeader::CppHeader(const std::string& include_guard, 420 const std::vector<std::string>& include_list, 421 unique_ptr<CppNamespace> a_namespace) 422 : Document(include_list, std::move(a_namespace)), 423 include_guard_(include_guard) {} 424 425 void CppHeader::Write(CodeWriter* to) const { 426 to->Write("#ifndef %s\n", include_guard_.c_str()); 427 to->Write("#define %s\n\n", include_guard_.c_str()); 428 429 Document::Write(to); 430 to->Write("\n"); 431 432 to->Write("#endif // %s", include_guard_.c_str()); 433 } 434 435 CppSource::CppSource(const std::vector<std::string>& include_list, 436 unique_ptr<CppNamespace> a_namespace) 437 : Document(include_list, std::move(a_namespace)) {} 438 439 } // namespace cpp 440 } // namespace aidl 441 } // namespace android 442