1/* 2 * Copyright (c) 2024-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16// Autogenerated file -- DO NOT EDIT! 17// NOLINTBEGIN(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-non-const-parameter) 18// NOLINTBEGIN(readability-function-size, readability-magic-numbers) 19 20% Enums::enums&.each do |name, enum| 21% if enum.flags&.length > 0 22extern "C" __attribute__((unused)) <%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 23end %>::<%= name %> E2pToIr<%= name %>(Es2panda<%= name %> e2pFlags) 24{ 25% if enum.type == 'unsigned' 26% if enum.flags.length <= 32 || enum.type == "int" 27 auto irFlags = (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 28end %>::<%= name %>)0U; 29% enum.flags&.each do |flag| 30 irFlags |= (e2pFlags & Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %>) != 0 ? <%= enum.namespace %><%= 31 if enum.parent_class_name then "::" + enum.parent_class_name 32end %>::<%= name %>::<%= flag %> : (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 33end %>::<%= name %>)0U; 34% end 35% else 36 auto irFlags = (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 37end %>::<%= name %>)0U; 38% enum.flags&.each_with_index do |flag, index| 39 irFlags |= (e2pFlags & <%= if index > 0 then "(uint64_t)1U << " + 40 (index - 1).to_s + "U" else "(uint64_t)0U" end %>) != 0 ? <%= 41 enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 42end %>::<%= name %>::<%= flag %> : (<%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 43end %>::<%= name %>)0U; 44% end 45% end 46 return irFlags; 47% else 48 switch(e2pFlags) 49 { 50% enum.flags&.each do |flag| 51 case Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %>: 52 return <%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 53end %>::<%= name %>::<%= flag %>; 54% end 55 default: 56 ES2PANDA_UNREACHABLE(); 57 } 58%end 59} 60% end 61 62%end 63 64% Enums::enums&.each do |name, enum| 65% if enum.flags&.length > 0 66extern "C" __attribute__((unused)) Es2panda<%= name %> IrToE2p<%= name %>(<%= 67enum.namespace %><%= if enum.parent_class_name then 68"::" + enum.parent_class_name end %>::<%= name %> irFlags) 69{ 70% if enum.type == 'unsigned' 71 Es2panda<%= name %> e2pFlags {(Es2panda<%= name %>)0U}; 72% if enum.flags.length <= 32 || enum.type == "int" 73% enum.flags&.each do |flag| 74 e2pFlags = static_cast<Es2panda<%= name %>>((irFlags & <%= enum.namespace %><%= if enum.parent_class_name then 75 "::" + enum.parent_class_name end %>::<%= name %>::<%= flag 76 %>) != 0 ? e2pFlags | Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %> : e2pFlags); 77% end 78% else 79% enum.flags&.each_with_index do |flag, index| 80 e2pFlags = static_cast<Es2panda<%= name %>>((irFlags & <%= enum.namespace %><%= if enum.parent_class_name then 81 "::" + enum.parent_class_name end %>::<%= name %>::<%= flag 82 %>) != 0 ? e2pFlags | <%= if index > 0 then "(uint64_t)1U << " + (index - 1).to_s + "U" 83 else "(uint64_t)0U" end %> : e2pFlags); 84% end 85% end 86 return e2pFlags; 87% else 88 switch(irFlags) 89 { 90% enum.flags&.each do |flag| 91 case <%= enum.namespace %><%= if enum.parent_class_name then "::" + enum.parent_class_name 92end %>::<%= name %>::<%= flag %>: 93 return Es2panda<%= name %>::<%= enum.name_to_upper_snake %>_<%= flag %>; 94% end 95 default: 96 ES2PANDA_UNREACHABLE(); 97 } 98% end 99} 100%end 101 102% end 103 104// NOLINTEND(readability-function-size, readability-magic-numbers) 105 106// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 107#define IS(public_name, e2p_name) \ 108 extern "C" bool Is##public_name(es2panda_AstNode *ast) \ 109 { \ 110 auto *node = reinterpret_cast<ir::AstNode *>(ast); \ 111 return node->Is##e2p_name(); \ 112 } 113 114% Es2pandaLibApi::ast_nodes&.each do |ast_node| 115% if ast_node != "AstNode" && ast_node != "TypeNode" 116IS(<%= ast_node %>, <%= ast_node %>) 117% end 118% end 119 120#undef IS 121 122// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 123#define IS(public_name, e2p_name) \ 124 extern "C" bool ScopeIs##public_name(es2panda_Scope *scope) \ 125 { \ 126 auto *e2p_scope = reinterpret_cast<varbinder::Scope *>(scope); \ 127 return e2p_scope->Is##e2p_name(); \ 128 } 129 130% Es2pandaLibApi::scopes&.each do |scope| 131% if scope != "Scope" 132IS(<%= scope %>, <%= scope %>) 133% end 134% end 135 136#undef IS 137 138// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 139#define IS(public_name, e2p_name) \ 140 extern "C" bool TypeIs##public_name(es2panda_Type *type) \ 141 { \ 142 auto *e2p_type = reinterpret_cast<checker::Type *>(type); \ 143 return e2p_type->Is##e2p_name(); \ 144 } 145 146% Es2pandaLibApi::ast_types&.each do |type| 147% if type != "Type" 148IS(<%= type %>, <%= type %>) 149% end 150% end 151 152#undef IS 153 154// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 155#define IS(public_name, e2p_name) \ 156 extern "C" bool VariableIs##public_name(es2panda_Variable *variable) \ 157 { \ 158 auto *e2p_variable = reinterpret_cast<varbinder::Variable *>(variable); \ 159 return e2p_variable->Is##e2p_name(); \ 160 } 161 162% Es2pandaLibApi::ast_variables&.each do |variable| 163% if variable[1] != "Variable" 164IS(<%= variable[1] %>, <%= variable[1] %>) 165% end 166% end 167 168#undef IS 169 170// NOLINTNEXTLINE(readability-function-size) 171char const *AstNodeName(es2panda_AstNode *ast) 172{ 173% Es2pandaLibApi::ast_nodes&.each do |ast_node| 174% unless ["AstNode", "Expression", "Statement", "TypeNode"].include?(ast_node) 175 if(Is<%= ast_node %>(ast)) { 176 return "<%= ast_node %>"; 177 } 178% end 179% end 180 if(IsExpression(ast)) { 181 return "Expression"; 182 } 183 if(IsStatement(ast)) { 184 return "Statement"; 185 } 186 return "Unknown AstNode"; 187} 188 189// NOLINTBEGIN(performance-for-range-copy, readability-identifier-naming) 190% Es2pandaLibApi::classes&.each do |namespaceName, namespaceClasses| 191% namespaceClasses&.each do |className, classData| 192 193% classData.class_constructors&.each_with_index do |constructor, index| 194/* <%= constructor["raw_decl"] %> */ 195extern "C" <%= classData.constructor_type().lib_type_to_str() 196%>Create<%= className + constructor["overload"] 197%>([[maybe_unused]] es2panda_Context *context 198<%= constructor["args"]&.map { |arg| if arg.lib_args_to_str.strip() != "" then 199", " + "[[maybe_unused]] " + arg.lib_args_to_str end }&.join("") %>) 200{ 201% constructor["args"]&.each do |arg| 202 <%= arg.lib_cast["expression"] %> 203% end 204 auto *ctx = reinterpret_cast<Context *>(context); 205 auto *ctxAllocator = ctx->allocator; 206% if classData.constructor_type().lib_type_to_str() == "es2panda_AstNode *" 207 auto *astNode = (<%= classData.constructor_cast["start"] 208 %><%= constructor["args"]&.map { |arg| arg.lib_cast["var_name"] }&.join(", ") %>)<%= 209 classData.constructor_cast["end"] %>; 210 astNode->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); 211 return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str() 212 %>>(astNode); 213% elsif 214 return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str() 215 %>>(<%= classData.constructor_cast["start"] 216 %><%= constructor["args"]&.map { |arg| arg.lib_cast["var_name"] }&.join(", ") %>)<%= 217 classData.constructor_cast["end"] %>; 218% end 219} 220 221% if classData.updater_allowed() 222 223/* Updater */ 224extern "C" <%= classData.constructor_type().lib_type_to_str() 225%>Update<%= className + constructor["overload"] 226%>([[maybe_unused]] es2panda_Context *context, es2panda_AstNode *original 227<%= constructor["args"]&.map { |arg| if arg.lib_args_to_str.strip() != "" then 228", " + "[[maybe_unused]] " + arg.lib_args_to_str end }&.join("") %>) 229{ 230% constructor["args"]&.each do |arg| 231 <%= arg.lib_cast["expression"] %> 232% end 233 auto *ctx = reinterpret_cast<Context *>(context); 234 auto *ctxAllocator = ctx->allocator; 235 auto newE2pNode = <%= classData.constructor_cast["start"] 236 %><%= constructor["args"]&.map { |arg| arg.lib_cast["var_name"] }&.join(", ") %><%= 237 classData.constructor_cast["end"] %>; 238 auto *e2pOriginal = reinterpret_cast<ir::AstNode *>(original); 239 newE2pNode->SetOriginalNode(e2pOriginal); 240 newE2pNode->SetParent(e2pOriginal->Parent()); 241 newE2pNode->SetRange(e2pOriginal->Range()); 242% if classData.constructor_type().lib_type_to_str() == "es2panda_AstNode *" 243 newE2pNode->AddAstNodeFlags(ir::AstNodeFlags::NOCLEANUP); 244% end 245% if className + constructor["overload"] == "MethodDefinition" 246 for (auto overload : e2pOriginal->AsMethodDefinition()->Overloads()) { 247 overload->SetBaseOverloadMethod(newE2pNode); 248 } 249 newE2pNode->AsMethodDefinition()->SetBaseOverloadMethod(e2pOriginal->AsMethodDefinition()->BaseOverloadMethod()); 250 if (e2pOriginal->AsMethodDefinition()->BaseOverloadMethod() != nullptr) { 251 auto originalOverloads = e2pOriginal->AsMethodDefinition()->BaseOverloadMethod()->Overloads(); 252 for (auto &overload : originalOverloads) { 253 if (overload == e2pOriginal) { 254 overload = newE2pNode; 255 } 256 } 257 e2pOriginal->AsMethodDefinition()->BaseOverloadMethod()->SetOverloads(std::move(originalOverloads)); 258 } 259 auto oriOverloads = e2pOriginal->AsMethodDefinition()->Overloads(); 260 newE2pNode->AsMethodDefinition()->SetOverloads(std::move(oriOverloads)); 261 262% end 263 return reinterpret_cast<<%= classData.constructor_type().lib_type_to_str() 264 %>>(newE2pNode); 265} 266 267%end # updater end 268 269% end # constructors end 270 271% classData.class_methods&.each_with_index do |method_info, index| 272/* <%= method_info["raw_decl"] %> */ 273extern "C" <%= method_info["return_type"].lib_type_to_str %><%= className + method_info["overload_name"] 274%>([[maybe_unused]] es2panda_Context *context<%= if classData.call_cast["call_var_str"] 275then ", " + classData.call_cast["call_var_str"] end %><%= 276method_info["args"]&.map { |arg| if arg.lib_args_to_str.strip() != "" then 277", " + "[[maybe_unused]] " + arg.lib_args_to_str end}&.join("") %>/*return_args:*/<%= method_info["return_arg_to_str"] %>) 278{ 279% method_info["args"]&.each do |arg| 280 <%= arg.lib_cast["expression"] %> 281% end 282 <%= method_info["return_expr"] %> 283} 284 285% end # methods end 286 287% end 288% end # classes end 289 290% Es2pandaLibApi::structs&.each do |structName, structData| 291 292% structData.struct_getters&.each_with_index do |method_info, index| 293extern "C" <%= method_info["return_type"].lib_type_to_str %><%= structName + method_info["name"] 294%>([[maybe_unused]] es2panda_Context *context<%= if structData.call_cast["call_var_str"] 295then structData.call_cast["call_var_str"] end %>/*return_args:*/<%= method_info["return_arg_to_str"] %>) 296{ 297% method_info["args"]&.each do |arg| 298 <%= arg.lib_cast["expression"] %> 299% end 300 <%= method_info["return_expr"] %> 301} 302 303% end # getters end 304 305% end # structs end 306 307 308% Es2pandaLibApi::print_stats 309// NOLINTEND(performance-for-range-copy, readability-identifier-naming) 310// NOLINTEND(cppcoreguidelines-pro-bounds-pointer-arithmetic, readability-non-const-parameter)