00001
00002
00003
00004
00005
00006 #include "langmap_generator.h"
00007 #include "be_extern.h"
00008
00009 #include "utl_identifier.h"
00010
00011 #include "ace/Version.h"
00012 #include "ace/CDR_Base.h"
00013 #ifdef ACE_HAS_CDR_FIXED
00014 #include "ast_fixed.h"
00015 #endif
00016
00017 #include <map>
00018 #include <iostream>
00019
00020 using namespace AstTypeClassification;
00021
00022 namespace {
00023 std::map<AST_PredefinedType::PredefinedType, std::string> primtype_;
00024
00025 enum Helper {
00026 HLP_STR_VAR, HLP_STR_OUT, HLP_WSTR_VAR, HLP_WSTR_OUT,
00027 HLP_STR_MGR, HLP_WSTR_MGR,
00028 HLP_FIX_VAR, HLP_VAR_VAR, HLP_OUT,
00029 HLP_SEQ, HLP_SEQ_NS, HLP_SEQ_VAR_VAR, HLP_SEQ_FIX_VAR, HLP_SEQ_OUT,
00030 HLP_ARR_VAR_VAR, HLP_ARR_FIX_VAR, HLP_ARR_OUT, HLP_ARR_FORANY,
00031 HLP_FIXED, HLP_FIXED_CONSTANT
00032 };
00033 std::map<Helper, std::string> helpers_;
00034
00035 std::string map_type(AST_Type* type)
00036 {
00037 if (AST_Typedef::narrow_from_decl(type)) {
00038 return scoped(type->name());
00039 }
00040 const Classification cls = classify(type);
00041 if (cls & CL_PRIMITIVE) {
00042 AST_Type* actual = resolveActualType(type);
00043 return primtype_[AST_PredefinedType::narrow_from_decl(actual)->pt()];
00044 }
00045 if (cls & CL_STRING) {
00046 const AST_PredefinedType::PredefinedType chartype = (cls & CL_WIDE)
00047 ? AST_PredefinedType::PT_wchar : AST_PredefinedType::PT_char;
00048 return primtype_[chartype] + '*';
00049 }
00050 if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_ARRAY | CL_ENUM | CL_FIXED)) {
00051 return scoped(type->name());
00052 }
00053 if (cls & CL_INTERFACE) {
00054 return scoped(type->name()) + "_var";
00055 }
00056 return "<<unknown>>";
00057 }
00058
00059 std::string map_type(AST_Expression::ExprType type)
00060 {
00061 AST_PredefinedType::PredefinedType pt = AST_PredefinedType::PT_void;
00062 switch (type)
00063 {
00064 case AST_Expression::EV_short: pt = AST_PredefinedType::PT_short; break;
00065 case AST_Expression::EV_ushort: pt = AST_PredefinedType::PT_ushort; break;
00066 case AST_Expression::EV_long: pt = AST_PredefinedType::PT_long; break;
00067 case AST_Expression::EV_ulong: pt = AST_PredefinedType::PT_ulong; break;
00068 case AST_Expression::EV_longlong: pt = AST_PredefinedType::PT_longlong; break;
00069 case AST_Expression::EV_ulonglong: pt = AST_PredefinedType::PT_ulonglong; break;
00070 case AST_Expression::EV_float: pt = AST_PredefinedType::PT_float; break;
00071 case AST_Expression::EV_double: pt = AST_PredefinedType::PT_double; break;
00072 case AST_Expression::EV_longdouble: pt = AST_PredefinedType::PT_longdouble; break;
00073 case AST_Expression::EV_char: pt = AST_PredefinedType::PT_char; break;
00074 case AST_Expression::EV_wchar: pt = AST_PredefinedType::PT_wchar; break;
00075 case AST_Expression::EV_octet: pt = AST_PredefinedType::PT_octet; break;
00076 case AST_Expression::EV_bool: pt = AST_PredefinedType::PT_boolean; break;
00077 case AST_Expression::EV_string: pt = AST_PredefinedType::PT_char; break;
00078 case AST_Expression::EV_wstring: pt = AST_PredefinedType::PT_wchar; break;
00079 #ifdef ACE_HAS_CDR_FIXED
00080 case AST_Expression::EV_fixed:
00081 be_global->add_include("FACE/Fixed.h", BE_GlobalData::STREAM_LANG_H);
00082 return helpers_[HLP_FIXED_CONSTANT];
00083 #endif
00084 default: break;
00085 }
00086 if (type == AST_Expression::EV_string || type == AST_Expression::EV_wstring)
00087 return primtype_[pt] + "* const";
00088 return primtype_[pt];
00089 }
00090
00091 std::string exporter() {
00092 return be_global->export_macro().empty() ? ""
00093 : be_global->export_macro().c_str() + std::string(" ");
00094 }
00095
00096 void struct_decls(UTL_ScopedName* name, AST_Type::SIZE_TYPE size, const char* struct_or_class = "struct")
00097 {
00098 be_global->add_include("<tao/VarOut_T.h>", BE_GlobalData::STREAM_LANG_H);
00099 const char* const nm = name->last_component()->get_string();
00100 be_global->lang_header_ <<
00101 struct_or_class << ' ' << nm << ";\n";
00102 switch (size) {
00103 case AST_Type::SIZE_UNKNOWN:
00104 be_global->lang_header_ << "/* Unknown size */\n";
00105 break;
00106 case AST_Type::FIXED:
00107 be_global->lang_header_ <<
00108 "typedef " << helpers_[HLP_FIX_VAR] << '<' << nm << "> " << nm << "_var;\n" <<
00109 "typedef " << nm << "& " << nm << "_out;\n";
00110 break;
00111 case AST_Type::VARIABLE:
00112 be_global->lang_header_ <<
00113 "typedef " << helpers_[HLP_VAR_VAR] << '<' << nm << "> " << nm << "_var;\n" <<
00114 "typedef " << helpers_[HLP_OUT] << '<' << nm << "> " << nm << "_out;\n";
00115 break;
00116 }
00117 }
00118
00119 std::string array_dims(AST_Type* type, ACE_CDR::ULong& elems) {
00120 AST_Array* const arr = AST_Array::narrow_from_decl(type);
00121 std::string ret;
00122 for (ACE_CDR::ULong dim = 0; dim < arr->n_dims(); ++dim) {
00123 elems *= arr->dims()[dim]->ev()->u.ulval;
00124 if (dim) ret += "[0]";
00125 }
00126 AST_Type* base = resolveActualType(arr->base_type());
00127 if (AST_Array::narrow_from_decl(base)) {
00128 ret += "[0]" + array_dims(base, elems);
00129 }
00130 return ret;
00131 }
00132
00133 void gen_typecode(UTL_ScopedName* name)
00134 {
00135 if (be_global->suppress_typecode()) {
00136 return;
00137 }
00138 const char* const nm = name->last_component()->get_string();
00139 be_global->lang_header_ <<
00140 "extern " << exporter() << "const ::CORBA::TypeCode_ptr _tc_" << nm
00141 << ";\n";
00142 const ScopedNamespaceGuard cppNs(name, be_global->impl_);
00143 be_global->impl_ <<
00144 "const ::CORBA::TypeCode_ptr _tc_" << nm << " = 0;\n";
00145 }
00146
00147 }
00148
00149 class GeneratorBase
00150 {
00151 public:
00152 virtual ~GeneratorBase() {}
00153 virtual void init() = 0;
00154 virtual void gen_sequence(UTL_ScopedName* tdname, AST_Sequence* seq) = 0;
00155 virtual bool gen_struct(AST_Structure* s, UTL_ScopedName* name, const std::vector<AST_Field*>& fields, AST_Type::SIZE_TYPE size, const char* x) = 0;
00156
00157 static std::string generateDefaultValue(AST_Union* the_union, AST_Type* discriminator)
00158 {
00159 std::stringstream first_label;
00160 AST_Union::DefaultValue dv;
00161 if (the_union->default_value(dv) == -1) {
00162 ACE_ERROR((LM_ERROR,
00163 ACE_TEXT("(%P|%t) ERROR: generateDefaultValue::")
00164 ACE_TEXT(" computing default value failed\n")));
00165 return first_label.str();
00166 }
00167
00168 switch (the_union->udisc_type ())
00169 {
00170 case AST_Expression::EV_short:
00171 first_label << dv.u.short_val;
00172 break;
00173 case AST_Expression::EV_ushort:
00174 first_label << dv.u.ushort_val;
00175 break;
00176 case AST_Expression::EV_long:
00177 first_label << dv.u.long_val;
00178 break;
00179 case AST_Expression::EV_ulong:
00180 first_label << dv.u.ulong_val;
00181 break;
00182 case AST_Expression::EV_char:
00183 first_label << (int)dv.u.char_val;
00184 break;
00185 case AST_Expression::EV_bool:
00186 first_label << (dv.u.bool_val == 0 ? "false" : "true");
00187 break;
00188 case AST_Expression::EV_enum:
00189 {
00190 AST_Enum* e = AST_Enum::narrow_from_decl(discriminator);
00191 first_label << scoped(e->value_to_name(dv.u.enum_val));
00192 break;
00193 }
00194 case AST_Expression::EV_longlong:
00195 first_label << dv.u.longlong_val;
00196 break;
00197 case AST_Expression::EV_ulonglong:
00198 first_label << dv.u.ulonglong_val;
00199 break;
00200 default:
00201 std::cerr << "Illegal discriminator for union\n";
00202 break;
00203 }
00204
00205 return first_label.str();
00206 }
00207
00208 struct GenerateGettersAndSetters
00209 {
00210 AST_Union* the_union;
00211 AST_Type* discriminator;
00212
00213 GenerateGettersAndSetters (AST_Union* u, AST_Type* d)
00214 : the_union(u)
00215 , discriminator(d)
00216 { }
00217
00218 void operator() (AST_UnionBranch* branch)
00219 {
00220 const char* field_name = branch->local_name()->get_string();
00221 std::stringstream first_label;
00222 {
00223 AST_UnionLabel* label = branch->label(0);
00224 if (label->label_kind() == AST_UnionLabel::UL_default) {
00225 first_label << generateDefaultValue(the_union, discriminator);
00226 } else if (discriminator->node_type() == AST_Decl::NT_enum) {
00227 first_label << getEnumLabel(label->label_val(), discriminator);
00228 } else {
00229 first_label << *label->label_val()->ev();
00230 }
00231 }
00232
00233 AST_Type* field_type = branch->field_type();
00234 const std::string field_type_string = map_type(field_type);
00235 AST_Type* actual_field_type = resolveActualType(field_type);
00236 const Classification cls = classify(actual_field_type);
00237 if (cls & (CL_PRIMITIVE | CL_ENUM)) {
00238 be_global->lang_header_ <<
00239 " void " << field_name << " (" << field_type_string << " x) {\n"
00240 " _reset();\n"
00241 " this->_u." << field_name << " = x;\n"
00242 " _discriminator = " << first_label.str() << ";\n"
00243 " }\n"
00244 " " << field_type_string << ' ' << field_name << " () const {\n"
00245 " return this->_u." << field_name << ";\n"
00246 " }\n";
00247 } else if (cls & CL_STRING) {
00248 const std::string& primtype = (cls & CL_WIDE) ? primtype_[AST_PredefinedType::PT_wchar] : primtype_[AST_PredefinedType::PT_char];
00249 const std::string& helper = (cls & CL_WIDE) ? helpers_[HLP_WSTR_VAR] : helpers_[HLP_STR_VAR];
00250 be_global->lang_header_ <<
00251 " void " << field_name << " (" << primtype << "* x) {\n"
00252 " _reset();\n" <<
00253 " this->_u." << field_name << " = x;\n"
00254 " _discriminator = " << first_label.str() << ";\n"
00255 " }\n"
00256 " void " << field_name << " (const " << primtype << "* x) {\n"
00257 " _reset();\n"
00258 " this->_u." << field_name << " = ::CORBA::string_dup(x);\n"
00259 " _discriminator = " << first_label.str() << ";\n"
00260 " }\n"
00261 " void " << field_name << " (const " << helper << "& x) {\n"
00262 " _reset();\n" <<
00263 " this->_u." << field_name << " = ::CORBA::string_dup(x.in());\n"
00264 " _discriminator = " << first_label.str() << ";\n"
00265 " }\n"
00266 " const " << primtype << "* " << field_name << " () const {\n"
00267 " return this->_u." << field_name << ";\n"
00268 " }\n";
00269 } else if (cls & CL_ARRAY) {
00270 be_global->lang_header_ <<
00271 " void " << field_name << " (" << field_type_string << " x) {\n"
00272 " _reset();\n" <<
00273 " this->_u." << field_name << " = " << field_type_string << "_dup(x);\n"
00274 " _discriminator = " << first_label.str() << ";\n"
00275 " }\n"
00276 " " << field_type_string << "_slice* " << field_name << " () const {\n"
00277 " return this->_u." << field_name << ";\n"
00278 " }\n";
00279 } else if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_FIXED)) {
00280 be_global->lang_header_ <<
00281 " void " << field_name << " (const " << field_type_string << "& x) {\n"
00282 " _reset();\n"
00283 " this->_u." << field_name << " = new " << field_type_string << "(x);\n"
00284 " _discriminator = " << first_label.str() << ";\n"
00285 " }\n"
00286 " const " << field_type_string << "& " << field_name << " () const {\n"
00287 " return *this->_u." << field_name << ";\n"
00288 " }\n"
00289 " " << field_type_string << "& " << field_name << " () {\n"
00290 " return *this->_u." << field_name << ";\n"
00291 " }\n";
00292 } else {
00293 std::cerr << "Unsupported type for union element\n";
00294 }
00295 }
00296 };
00297
00298 static bool hasDefaultLabel (const std::vector<AST_UnionBranch*>& branches)
00299 {
00300 for (std::vector<AST_UnionBranch*>::const_iterator pos = branches.begin(), limit = branches.end();
00301 pos != limit;
00302 ++pos) {
00303 AST_UnionBranch* branch = *pos;
00304 for (unsigned long j = 0; j < branch->label_list_length(); ++j) {
00305 AST_UnionLabel* label = branch->label(j);
00306 if (label->label_kind() == AST_UnionLabel::UL_default) {
00307 return true;
00308 }
00309 }
00310 }
00311 return false;
00312 }
00313
00314 static size_t countLabels (const std::vector<AST_UnionBranch*>& branches)
00315 {
00316 size_t count = 0;
00317
00318 for (std::vector<AST_UnionBranch*>::const_iterator pos = branches.begin(), limit = branches.end();
00319 pos != limit;
00320 ++pos) {
00321 count += (*pos)->label_list_length();
00322 }
00323
00324 return count;
00325 }
00326
00327 static bool needsDefault (const std::vector<AST_UnionBranch*>& branches, AST_Type* discriminator)
00328 {
00329 return !hasDefaultLabel(branches) && needSyntheticDefault(discriminator, countLabels(branches));
00330 }
00331
00332 static void generate_union_field (AST_UnionBranch* branch)
00333 {
00334 AST_Type* field_type = branch->field_type();
00335 AST_Type* actual_field_type = resolveActualType(field_type);
00336 const Classification cls = classify(actual_field_type);
00337 if (cls & (CL_PRIMITIVE | CL_ENUM)) {
00338 be_global->lang_header_ <<
00339 " " << map_type(field_type) << ' ' << branch->local_name()->get_string() << ";\n";
00340 } else if (cls & CL_STRING) {
00341 const AST_PredefinedType::PredefinedType chartype = (cls & CL_WIDE)
00342 ? AST_PredefinedType::PT_wchar : AST_PredefinedType::PT_char;
00343 be_global->lang_header_ <<
00344 " " << primtype_[chartype] << "* " << branch->local_name()->get_string() << ";\n";
00345 } else if (cls & CL_ARRAY) {
00346 be_global->lang_header_ <<
00347 " " << map_type(field_type) << "_slice* " << branch->local_name()->get_string() << ";\n";
00348 } else if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_FIXED)) {
00349 be_global->lang_header_ <<
00350 " " << map_type(field_type) << "* " << branch->local_name()->get_string() << ";\n";
00351 } else {
00352 std::cerr << "Unsupported type for union element\n";
00353 }
00354 }
00355
00356 static std::string generateCopyCtor(const std::string& name, AST_Type* field_type,
00357 const std::string&, std::string&,
00358 const std::string&)
00359 {
00360 std::stringstream ss;
00361 AST_Type* actual_field_type = resolveActualType(field_type);
00362 const Classification cls = classify(actual_field_type);
00363 if (cls & (CL_PRIMITIVE | CL_ENUM)) {
00364 ss <<
00365 " this->_u." << name << " = other._u." << name << ";\n";
00366 } else if (cls & CL_STRING) {
00367 ss <<
00368 " this->_u." << name << " = (other._u." << name << ") ? ::CORBA::string_dup(other._u." << name << ") : 0 ;\n";
00369 } else if (cls & CL_ARRAY) {
00370 ss <<
00371 " this->_u." << name << " = (other._u." << name << ") ? " << map_type(field_type) << "_dup(other._u." << name << ") : 0 ;\n";
00372 } else if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_FIXED)) {
00373 ss <<
00374 " this->_u." << name << " = (other._u." << name << ") ? new " << map_type(field_type) << "(*other._u." << name << ") : 0;\n";
00375 } else {
00376 std::cerr << "Unsupported type for union element\n";
00377 }
00378
00379 return ss.str();
00380 }
00381
00382 static std::string generateAssign(const std::string& name, AST_Type* field_type,
00383 const std::string&, std::string&,
00384 const std::string&)
00385 {
00386 std::stringstream ss;
00387 AST_Type* actual_field_type = resolveActualType(field_type);
00388 const Classification cls = classify(actual_field_type);
00389 if (cls & (CL_PRIMITIVE | CL_ENUM)) {
00390 ss <<
00391 " this->_u." << name << " = other._u." << name << ";\n";
00392 } else if (cls & CL_STRING) {
00393 ss <<
00394 " this->_u." << name << " = (other._u." << name << ") ? ::CORBA::string_dup(other._u." << name << ") : 0 ;\n";
00395 } else if (cls & CL_ARRAY) {
00396 ss <<
00397 " this->_u." << name << " = (other._u." << name << ") ? " << map_type(field_type) << "_dup(other._u." << name << ") : 0 ;\n";
00398 } else if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_FIXED)) {
00399 ss <<
00400 " this->_u." << name << " = (other._u." << name << ") ? new " << map_type(field_type) << "(*other._u." << name << ") : 0;\n";
00401 } else {
00402 std::cerr << "Unsupported type for union element\n";
00403 }
00404
00405 return ss.str();
00406 }
00407
00408 static std::string generateEqual(const std::string& name, AST_Type* field_type,
00409 const std::string&, std::string&,
00410 const std::string&)
00411 {
00412 std::stringstream ss;
00413
00414 AST_Type* actual_field_type = resolveActualType(field_type);
00415 const Classification cls = classify(actual_field_type);
00416 if (cls & (CL_PRIMITIVE | CL_ENUM)) {
00417 ss <<
00418 " return this->_u." << name << " == rhs._u." << name << ";\n";
00419 } else if (cls & CL_STRING) {
00420 ss <<
00421 " return std::strcmp (this->_u." << name << ", rhs._u." << name << ") == 0 ;\n";
00422 } else if (cls & CL_ARRAY) {
00423
00424 ss <<
00425 " return false;\n";
00426 } else if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_FIXED)) {
00427 ss <<
00428 " return *this->_u." << name << " == *rhs._u." << name << ";\n";
00429 } else {
00430 std::cerr << "Unsupported type for union element\n";
00431 }
00432
00433 return ss.str();
00434 }
00435
00436 static std::string generateReset(const std::string& name, AST_Type* field_type,
00437 const std::string&, std::string&,
00438 const std::string&)
00439 {
00440 std::stringstream ss;
00441
00442 AST_Type* actual_field_type = resolveActualType(field_type);
00443 const Classification cls = classify(actual_field_type);
00444 if (cls & (CL_PRIMITIVE | CL_ENUM)) {
00445
00446 } else if (cls & CL_STRING) {
00447 ss <<
00448 " ::CORBA::string_free(this->_u." << name << ");\n"
00449 " this->_u." << name << " = 0;\n";
00450 } else if (cls & CL_ARRAY) {
00451 ss <<
00452 " " << map_type(field_type) << "_free(this->_u." << name << ");\n"
00453 " this->_u." << name << " = 0;\n";
00454 } else if (cls & (CL_STRUCTURE | CL_UNION | CL_SEQUENCE | CL_FIXED)) {
00455 ss <<
00456 " delete this->_u." << name << ";\n"
00457 " this->_u." << name << " = 0;\n";
00458 } else {
00459 std::cerr << "Unsupported type for union element\n";
00460 }
00461
00462 return ss.str();
00463 }
00464
00465 bool gen_union(AST_Union* u, UTL_ScopedName* name, const std::vector<AST_UnionBranch*>& branches, AST_Type* discriminator)
00466 {
00467 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
00468 const char* const nm = name->last_component()->get_string();
00469 struct_decls(name, u->size_type(), "class");
00470 be_global->lang_header_ <<
00471 "\n"
00472 "class " << exporter() << nm << " \n"
00473 "{\n"
00474 " public:\n"
00475 " typedef " << nm << "_var _var_type;\n"
00476 " typedef " << nm << "_out _out_type;\n"
00477 " " << nm << "();\n"
00478 " " << nm << "(const " << nm << "&);\n"
00479 " ~" << nm << "() { _reset(); };\n"
00480 " " << nm << "& operator=(const " << nm << "&);\n"
00481 " void _d(" << scoped(discriminator->name()) << " d) { _discriminator = d; }\n"
00482 " " << scoped(discriminator->name()) << " _d() const { return _discriminator; }\n";
00483
00484 std::for_each (branches.begin(), branches.end(), GenerateGettersAndSetters(u, discriminator));
00485
00486 if (needsDefault(branches, discriminator)) {
00487 be_global->lang_header_ <<
00488 " void _default() {\n"
00489 " _reset();\n"
00490 " _discriminator = " << generateDefaultValue(u, discriminator) << ";\n"
00491 " }\n";
00492 }
00493
00494 be_global->lang_header_ <<
00495 " bool operator==(const " << nm << "& rhs) const;\n"
00496 " bool operator!=(const " << nm << "& rhs) const { return !(*this == rhs); }\n"
00497 " OPENDDS_POOL_ALLOCATION_HOOKS\n";
00498
00499 be_global->lang_header_ <<
00500 " private:\n"
00501 " " << scoped(discriminator->name()) << " _discriminator;\n"
00502 " union {\n";
00503
00504 std::for_each (branches.begin(), branches.end(), generate_union_field);
00505
00506 be_global->lang_header_ <<
00507 " } _u;\n";
00508
00509 be_global->lang_header_ <<
00510 " void _reset();\n"
00511 "};\n\n";
00512
00513 be_global->add_include("dds/DCPS/PoolAllocationBase.h", BE_GlobalData::STREAM_LANG_H);
00514 be_global->add_include("<ace/CDR_Stream.h>", BE_GlobalData::STREAM_LANG_H);
00515
00516 be_global->lang_header_ <<
00517 exporter() << "ACE_CDR::Boolean operator<< (ACE_OutputCDR& os, const " << nm << "& x);\n\n";
00518 be_global->lang_header_ <<
00519 exporter() << "ACE_CDR::Boolean operator>> (ACE_InputCDR& os, " << nm << "& x);\n\n";
00520
00521 {
00522 const ScopedNamespaceGuard guard(name, be_global->impl_);
00523
00524 be_global->impl_ <<
00525 nm << "::" << nm << "() { std::memset (this, 0, sizeof (" << nm << ")); }\n\n";
00526
00527 be_global->impl_ <<
00528 nm << "::" << nm << "(const " << nm << "& other)\n"
00529 "{\n"
00530 " this->_discriminator = other._discriminator;\n";
00531 generateSwitchForUnion("this->_discriminator", generateCopyCtor, branches, discriminator, "", "", "", false, false);
00532 be_global->impl_ <<
00533 "}\n\n";
00534
00535 be_global->impl_ <<
00536 nm << "& " << nm << "::operator=(const " << nm << "& other)\n"
00537 "{\n" <<
00538 " if (this == &other) {\n"
00539 " return *this;\n"
00540 " }\n\n"
00541 " _reset();\n"
00542 " this->_discriminator = other._discriminator;\n";
00543 generateSwitchForUnion("this->_discriminator", generateAssign, branches, discriminator, "", "", "", false, false);
00544 be_global->impl_ <<
00545 " return *this;\n"
00546 "}\n\n";
00547
00548 be_global->impl_ <<
00549 "bool " << nm << "::operator==(const " << nm << "& rhs) const\n"
00550 "{\n"
00551 " if (this->_discriminator != rhs._discriminator) return false;\n";
00552 if (generateSwitchForUnion("this->_discriminator", generateEqual, branches, discriminator, "", "", "", false, false)) {
00553 be_global->impl_ <<
00554 " return false;\n";
00555 }
00556 be_global->impl_ <<
00557 "}\n\n";
00558
00559 be_global->impl_ <<
00560 "void " << nm << "::_reset()\n"
00561 "{\n";
00562 generateSwitchForUnion("this->_discriminator", generateReset, branches, discriminator, "", "", "", false, false);
00563 be_global->impl_ <<
00564 "}\n\n";
00565
00566 be_global->impl_ <<
00567 "ACE_CDR::Boolean operator<<(ACE_OutputCDR&, const " << nm << "&) { return true; }\n\n";
00568 be_global->impl_ <<
00569 "ACE_CDR::Boolean operator>>(ACE_InputCDR&, " << nm << "&) { return true; }\n\n";
00570 }
00571
00572 gen_typecode(name);
00573 return true;
00574 }
00575 };
00576
00577 class FaceGenerator : public GeneratorBase
00578 {
00579 public:
00580 virtual void init()
00581 {
00582 be_global->add_include("FACE/types.hpp", BE_GlobalData::STREAM_LANG_H);
00583 be_global->add_include("FACE/StringManager.h", BE_GlobalData::STREAM_LANG_H);
00584 primtype_[AST_PredefinedType::PT_long] = "::FACE::Long";
00585 primtype_[AST_PredefinedType::PT_ulong] = "::FACE::UnsignedLong";
00586 primtype_[AST_PredefinedType::PT_longlong] = "::FACE::LongLong";
00587 primtype_[AST_PredefinedType::PT_ulonglong] = "::FACE::UnsignedLongLong";
00588 primtype_[AST_PredefinedType::PT_short] = "::FACE::Short";
00589 primtype_[AST_PredefinedType::PT_ushort] = "::FACE::UnsignedShort";
00590 primtype_[AST_PredefinedType::PT_float] = "::FACE::Float";
00591 primtype_[AST_PredefinedType::PT_double] = "::FACE::Double";
00592 primtype_[AST_PredefinedType::PT_longdouble] = "::FACE::LongDouble";
00593 primtype_[AST_PredefinedType::PT_char] = "::FACE::Char";
00594 primtype_[AST_PredefinedType::PT_wchar] = "::FACE::WChar";
00595 primtype_[AST_PredefinedType::PT_boolean] = "::FACE::Boolean";
00596 primtype_[AST_PredefinedType::PT_octet] = "::FACE::Octet";
00597 helpers_[HLP_STR_VAR] = "::FACE::String_var";
00598 helpers_[HLP_STR_OUT] = "::FACE::String_out";
00599 helpers_[HLP_WSTR_VAR] = "::FACE::WString_var";
00600 helpers_[HLP_WSTR_OUT] = "::FACE::WString_out";
00601 helpers_[HLP_STR_MGR] = "::OpenDDS::FaceTypes::String_mgr";
00602 helpers_[HLP_WSTR_MGR] = "::OpenDDS::FaceTypes::WString_mgr";
00603 helpers_[HLP_FIX_VAR] = "::TAO_Fixed_Var_T";
00604 helpers_[HLP_VAR_VAR] = "::TAO_Var_Var_T";
00605 helpers_[HLP_OUT] = "::TAO_Out_T";
00606 helpers_[HLP_SEQ] = "::OpenDDS::FaceTypes::Sequence";
00607 helpers_[HLP_SEQ_NS] = "::OpenDDS::FaceTypes";
00608 helpers_[HLP_SEQ_VAR_VAR] = "::OpenDDS::FaceTypes::SequenceVar";
00609 helpers_[HLP_SEQ_FIX_VAR] = "::OpenDDS::FaceTypes::SequenceVar";
00610 helpers_[HLP_SEQ_OUT] = "::TAO_Seq_Out_T";
00611 helpers_[HLP_ARR_VAR_VAR] = "::TAO_VarArray_Var_T";
00612 helpers_[HLP_ARR_FIX_VAR] = "::TAO_FixedArray_Var_T";
00613 helpers_[HLP_ARR_OUT] = "::TAO_Array_Out_T";
00614 helpers_[HLP_ARR_FORANY] = "::TAO_Array_Forany_T";
00615 helpers_[HLP_FIXED] = "::OpenDDS::FaceTypes::Fixed_T";
00616 helpers_[HLP_FIXED_CONSTANT] = "::OpenDDS::FaceTypes::Fixed";
00617 }
00618
00619 void gen_sequence(UTL_ScopedName* tdname, AST_Sequence* seq)
00620 {
00621 be_global->add_include("<tao/Seq_Out_T.h>", BE_GlobalData::STREAM_LANG_H);
00622 be_global->add_include("FACE/Sequence.h", BE_GlobalData::STREAM_LANG_H);
00623 be_global->add_include("FACE/SequenceVar.h", BE_GlobalData::STREAM_LANG_H);
00624 be_global->add_include("<ace/CDR_Stream.h>", BE_GlobalData::STREAM_LANG_H);
00625 const char* const nm = tdname->last_component()->get_string();
00626 AST_Type* elem = seq->base_type();
00627 const Classification elem_cls = classify(elem);
00628 const bool bounded = !seq->unbounded();
00629 const Helper var = (elem->size_type() == AST_Type::VARIABLE)
00630 ? HLP_SEQ_VAR_VAR : HLP_SEQ_FIX_VAR,
00631 out = HLP_SEQ_OUT;
00632
00633 std::string elem_type = map_type(elem), extra_tmp_args;
00634 if (elem_cls & CL_STRING) {
00635 const AST_Expression::ExprType char_type = (elem_cls & CL_WIDE)
00636 ? AST_Expression::EV_wchar : AST_Expression::EV_char;
00637 extra_tmp_args = ", " + helpers_[HLP_SEQ_NS] + "::StringEltPolicy< "
00638 + map_type(char_type) + ">";
00639 } else if (elem_cls & CL_ARRAY) {
00640 extra_tmp_args = ", " + helpers_[HLP_SEQ_NS] + "::ArrayEltPolicy<"
00641 + elem_type + "_forany>";
00642 } else if (elem->size_type() == AST_Type::VARIABLE) {
00643 extra_tmp_args = ", " + helpers_[HLP_SEQ_NS] + "::VariEltPolicy<"
00644 + elem_type + ">";
00645 }
00646
00647 std::string bound = helpers_[HLP_SEQ_NS] + "::Unbounded";
00648 if (bounded) {
00649 std::ostringstream oss;
00650 oss << helpers_[HLP_SEQ_NS] << "::Bounded<"
00651 << seq->max_size()->ev()->u.ulval << '>';
00652 bound = oss.str();
00653 }
00654
00655 const std::string base = helpers_[HLP_SEQ] + "< " + elem_type + ", " + bound
00656 + extra_tmp_args + " >",
00657 len_type = primtype_[AST_PredefinedType::PT_ulong],
00658 flag_type = primtype_[AST_PredefinedType::PT_boolean];
00659
00660 be_global->lang_header_ <<
00661 "class " << nm << ";\n"
00662 "typedef " << helpers_[var] << '<' << nm << "> " << nm << "_var;\n"
00663 "typedef " << helpers_[out] << '<' << nm << "> " << nm << "_out;\n\n"
00664 "class " << exporter() << nm << " : public " << base << " {\n"
00665 "public:\n"
00666 " typedef " << nm << "_var _var_type;\n"
00667 " typedef " << nm << "_out _out_type;\n\n"
00668 " " << nm << "() {}\n"
00669 " " << nm << "(const " << nm << "& seq) : " << base << "(seq) {}\n"
00670 " friend void swap(" << nm << "& a, " << nm << "& b) { a.swap(b); }\n"
00671 " " << nm << "& operator=(const " << nm << "& rhs)\n"
00672 " {\n"
00673 " " << nm << " tmp(rhs);\n"
00674 " swap(tmp);\n"
00675 " return *this;\n"
00676 " }\n";
00677
00678 if (bounded) {
00679 be_global->lang_header_ <<
00680 " " << nm << "(" << len_type << " length, " << elem_type << "* data, "
00681 << flag_type << " release = false)\n"
00682 " : " << base << "(0u, length, data, release) {}\n";
00683 } else {
00684 be_global->lang_header_ <<
00685 " " << nm << "(" << len_type << " maximum)\n"
00686 " : " << base << "(maximum, 0u, 0, true) {}\n"
00687 " " << nm << "(" << len_type << " maximum, " << len_type << " length, "
00688 << elem_type << "* data, " << flag_type << " release = false)\n"
00689 " : " << base << "(maximum, length, data, release) {}\n";
00690 }
00691 be_global->lang_header_ <<
00692 "};\n\n";
00693
00694 be_global->lang_header_ <<
00695 "inline ACE_CDR::Boolean operator<< (ACE_OutputCDR&, const " << nm << "&) { return true; }\n\n";
00696
00697 be_global->lang_header_ <<
00698 "inline ACE_CDR::Boolean operator>> (ACE_InputCDR&, " << nm << "&) { return true; }\n\n";
00699 }
00700
00701 bool gen_struct(AST_Structure*, UTL_ScopedName* name,
00702 const std::vector<AST_Field*>& fields,
00703 AST_Type::SIZE_TYPE size,
00704 const char*)
00705 {
00706 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
00707 const char* const nm = name->last_component()->get_string();
00708 struct_decls(name, size);
00709 be_global->lang_header_ <<
00710 "\n"
00711 "struct " << exporter() << nm << "\n"
00712 "{\n"
00713 " typedef " << nm << "_var _var_type;\n"
00714 " typedef " << nm << "_out _out_type;\n\n";
00715
00716 for (size_t i = 0; i < fields.size(); ++i) {
00717 AST_Type* field_type = fields[i]->field_type();
00718 const std::string field_name = fields[i]->local_name()->get_string();
00719 std::string type_name = map_type(field_type);
00720 const Classification cls = classify(field_type);
00721 if (cls & CL_STRING) {
00722 type_name = helpers_[(cls & CL_WIDE) ? HLP_WSTR_MGR : HLP_STR_MGR];
00723 }
00724 be_global->lang_header_ <<
00725 " " << type_name << ' ' << field_name << ";\n";
00726 }
00727
00728 be_global->lang_header_ << "\n"
00729 " bool operator==(const " << nm << "& rhs) const;\n"
00730 " bool operator!=(const " << nm << "& rhs) const { return !(*this == rhs); }\n"
00731 " OPENDDS_POOL_ALLOCATION_HOOKS\n"
00732 "};\n\n";
00733
00734 be_global->add_include("dds/DCPS/PoolAllocationBase.h", BE_GlobalData::STREAM_LANG_H);
00735 be_global->add_include("<ace/CDR_Stream.h>", BE_GlobalData::STREAM_LANG_H);
00736
00737 if (size == AST_Type::VARIABLE) {
00738 be_global->lang_header_ <<
00739 exporter() << "void swap(" << nm << "& lhs, " << nm << "& rhs);\n\n";
00740 }
00741
00742 be_global->lang_header_ <<
00743 exporter() << "ACE_CDR::Boolean operator<< (ACE_OutputCDR& os, const " << nm << "& x);\n\n";
00744 be_global->lang_header_ <<
00745 exporter() << "ACE_CDR::Boolean operator>> (ACE_InputCDR& os, " << nm << "& x);\n\n";
00746
00747 {
00748 const ScopedNamespaceGuard guard(name, be_global->impl_);
00749 be_global->impl_ <<
00750 "bool " << nm << "::operator==(const " << nm << "& rhs) const\n"
00751 "{\n";
00752 for (size_t i = 0; i < fields.size(); ++i) {
00753 const std::string field_name = fields[i]->local_name()->get_string();
00754 AST_Type* field_type = resolveActualType(fields[i]->field_type());
00755 const Classification cls = classify(field_type);
00756 if (cls & CL_ARRAY) {
00757 std::string indent(" ");
00758 NestedForLoops nfl("int", "i",
00759 AST_Array::narrow_from_decl(field_type), indent, true);
00760 be_global->impl_ <<
00761 indent << "if (" << field_name << nfl.index_ << " != rhs."
00762 << field_name << nfl.index_ << ") {\n" <<
00763 indent << " return false;\n" <<
00764 indent << "}\n";
00765 } else {
00766 be_global->impl_ <<
00767 " if (" << field_name << " != rhs." << field_name << ") {\n"
00768 " return false;\n"
00769 " }\n";
00770 }
00771 }
00772 be_global->impl_ << " return true;\n}\n\n";
00773
00774 if (size == AST_Type::VARIABLE) {
00775 be_global->impl_ <<
00776 "void swap(" << nm << "& lhs, " << nm << "& rhs)\n"
00777 "{\n"
00778 " using std::swap;\n";
00779 for (size_t i = 0; i < fields.size(); ++i) {
00780 const std::string fn = fields[i]->local_name()->get_string();
00781 AST_Type* field_type = resolveActualType(fields[i]->field_type());
00782 const Classification cls = classify(field_type);
00783 if (cls & CL_ARRAY) {
00784 ACE_CDR::ULong elems = 1;
00785 const std::string flat_fn = fn + array_dims(field_type, elems);
00786 be_global->add_include("<algorithm>", BE_GlobalData::STREAM_CPP);
00787 be_global->impl_ <<
00788 " std::swap_ranges(lhs." << flat_fn << ", lhs." << flat_fn
00789 << " + " << elems << ", rhs." << flat_fn << ");\n";
00790 } else {
00791 be_global->impl_ <<
00792 " swap(lhs." << fn << ", rhs." << fn << ");\n";
00793 }
00794 }
00795 be_global->impl_ << "}\n\n";
00796 }
00797
00798 be_global->impl_ <<
00799 "ACE_CDR::Boolean operator<< (ACE_OutputCDR &, const " << nm << "&) { return true; }\n\n";
00800 be_global->impl_ <<
00801 "ACE_CDR::Boolean operator>> (ACE_InputCDR &, " << nm << "&) { return true; }\n\n";
00802 }
00803
00804 gen_typecode(name);
00805 return true;
00806 }
00807
00808 static FaceGenerator instance;
00809 };
00810 FaceGenerator FaceGenerator::instance;
00811
00812 class SafetyProfileGenerator : public GeneratorBase
00813 {
00814 public:
00815 virtual void init()
00816 {
00817 be_global->add_include("tao/String_Manager_T.h", BE_GlobalData::STREAM_LANG_H);
00818 be_global->add_include("tao/CORBA_String.h", BE_GlobalData::STREAM_LANG_H);
00819 primtype_[AST_PredefinedType::PT_long] = "CORBA::Long";
00820 primtype_[AST_PredefinedType::PT_ulong] = "CORBA::ULong";
00821 primtype_[AST_PredefinedType::PT_longlong] = "CORBA::LongLong";
00822 primtype_[AST_PredefinedType::PT_ulonglong] = "CORBA::UnsignedLongLong";
00823 primtype_[AST_PredefinedType::PT_short] = "CORBA::Short";
00824 primtype_[AST_PredefinedType::PT_ushort] = "CORBA::UShort";
00825 primtype_[AST_PredefinedType::PT_float] = "CORBA::Float";
00826 primtype_[AST_PredefinedType::PT_double] = "CORBA::Double";
00827 primtype_[AST_PredefinedType::PT_longdouble] = "CORBA::LongDouble";
00828 primtype_[AST_PredefinedType::PT_char] = "CORBA::Char";
00829 primtype_[AST_PredefinedType::PT_wchar] = "CORBA::WChar";
00830 primtype_[AST_PredefinedType::PT_boolean] = "CORBA::Boolean";
00831 primtype_[AST_PredefinedType::PT_octet] = "CORBA::Octet";
00832 helpers_[HLP_STR_VAR] = "CORBA::String_var";
00833 helpers_[HLP_STR_OUT] = "CORBA::String_out";
00834 helpers_[HLP_WSTR_VAR] = "CORBA::WString_var";
00835 helpers_[HLP_WSTR_OUT] = "CORBA::WString_out";
00836 helpers_[HLP_STR_MGR] = "::TAO::String_Manager";
00837 helpers_[HLP_WSTR_MGR] = "CORBA::WString_mgr";
00838 helpers_[HLP_FIX_VAR] = "::TAO_Fixed_Var_T";
00839 helpers_[HLP_VAR_VAR] = "::TAO_Var_Var_T";
00840 helpers_[HLP_OUT] = "::TAO_Out_T";
00841 helpers_[HLP_SEQ] = "::OpenDDS::SafetyProfile::Sequence";
00842 helpers_[HLP_SEQ_NS] = "::OpenDDS::SafetyProfile";
00843 helpers_[HLP_SEQ_VAR_VAR] = "::OpenDDS::SafetyProfile::SequenceVar";
00844 helpers_[HLP_SEQ_FIX_VAR] = "::OpenDDS::SafetyProfile::SequenceVar";
00845 helpers_[HLP_SEQ_OUT] = "::TAO_Seq_Out_T";
00846 helpers_[HLP_ARR_VAR_VAR] = "::TAO_VarArray_Var_T";
00847 helpers_[HLP_ARR_FIX_VAR] = "::TAO_FixedArray_Var_T";
00848 helpers_[HLP_ARR_OUT] = "::TAO_Array_Out_T";
00849 helpers_[HLP_ARR_FORANY] = "::TAO_Array_Forany_T";
00850 }
00851
00852 virtual void gen_sequence(UTL_ScopedName* tdname, AST_Sequence* seq)
00853 {
00854 be_global->add_include("<tao/Seq_Out_T.h>", BE_GlobalData::STREAM_LANG_H);
00855 be_global->add_include("dds/DCPS/SafetyProfileSequence.h", BE_GlobalData::STREAM_LANG_H);
00856 be_global->add_include("dds/DCPS/SafetyProfileSequenceVar.h", BE_GlobalData::STREAM_LANG_H);
00857 const char* const nm = tdname->last_component()->get_string();
00858 AST_Type* elem = seq->base_type();
00859 const Classification elem_cls = classify(elem);
00860 const bool bounded = !seq->unbounded();
00861 const Helper var = (elem->size_type() == AST_Type::VARIABLE)
00862 ? HLP_SEQ_VAR_VAR : HLP_SEQ_FIX_VAR,
00863 out = HLP_SEQ_OUT;
00864
00865 std::string elem_type = map_type(elem), extra_tmp_args;
00866 if (elem_cls & CL_STRING) {
00867 const AST_Expression::ExprType char_type = (elem_cls & CL_WIDE)
00868 ? AST_Expression::EV_wchar : AST_Expression::EV_char;
00869 extra_tmp_args = ", " + helpers_[HLP_SEQ_NS] + "::StringEltPolicy< "
00870 + map_type(char_type) + ">";
00871 } else if (elem_cls & CL_ARRAY) {
00872 extra_tmp_args = ", " + helpers_[HLP_SEQ_NS] + "::ArrayEltPolicy<"
00873 + elem_type + "_forany>";
00874 } else if (elem->size_type() == AST_Type::VARIABLE) {
00875 extra_tmp_args = ", " + helpers_[HLP_SEQ_NS] + "::VariEltPolicy<"
00876 + elem_type + ">";
00877 }
00878
00879 std::string bound = helpers_[HLP_SEQ_NS] + "::Unbounded";
00880 if (bounded) {
00881 std::ostringstream oss;
00882 oss << helpers_[HLP_SEQ_NS] << "::Bounded<"
00883 << seq->max_size()->ev()->u.ulval << '>';
00884 bound = oss.str();
00885 }
00886
00887 const std::string base = helpers_[HLP_SEQ] + "< " + elem_type + ", " + bound
00888 + extra_tmp_args + " >",
00889 len_type = primtype_[AST_PredefinedType::PT_ulong],
00890 flag_type = primtype_[AST_PredefinedType::PT_boolean];
00891
00892 be_global->lang_header_ <<
00893 "class " << nm << ";\n"
00894 "typedef " << helpers_[var] << '<' << nm << "> " << nm << "_var;\n"
00895 "typedef " << helpers_[out] << '<' << nm << "> " << nm << "_out;\n\n"
00896 "class " << exporter() << nm << " : public " << base << " {\n"
00897 "public:\n"
00898 " typedef " << nm << "_var _var_type;\n"
00899 " typedef " << nm << "_out _out_type;\n\n"
00900 " " << nm << "() {}\n"
00901 " " << nm << "(const " << nm << "& seq) : " << base << "(seq) {}\n"
00902 " friend void swap(" << nm << "& a, " << nm << "& b) { a.swap(b); }\n"
00903 " " << nm << "& operator=(const " << nm << "& rhs)\n"
00904 " {\n"
00905 " " << nm << " tmp(rhs);\n"
00906 " swap(tmp);\n"
00907 " return *this;\n"
00908 " }\n";
00909
00910 if (bounded) {
00911 be_global->lang_header_ <<
00912 " " << nm << "(" << len_type << " length, " << elem_type << "* data, "
00913 << flag_type << " release = false)\n"
00914 " : " << base << "(0u, length, data, release) {}\n";
00915 } else {
00916 be_global->lang_header_ <<
00917 " " << nm << "(" << len_type << " maximum)\n"
00918 " : " << base << "(maximum, 0u, 0, true) {}\n"
00919 " " << nm << "(" << len_type << " maximum, " << len_type << " length, "
00920 << elem_type << "* data, " << flag_type << " release = false)\n"
00921 " : " << base << "(maximum, length, data, release) {}\n";
00922 }
00923 be_global->lang_header_ <<
00924 "};\n\n";
00925
00926 be_global->lang_header_ <<
00927 "inline ACE_CDR::Boolean operator<< (ACE_OutputCDR&, const " << nm << "&) { return true; }\n\n";
00928
00929 be_global->lang_header_ <<
00930 "inline ACE_CDR::Boolean operator>> (ACE_InputCDR&, " << nm << "&) { return true; }\n\n";
00931 }
00932
00933 bool gen_struct(AST_Structure*, UTL_ScopedName* name,
00934 const std::vector<AST_Field*>& fields,
00935 AST_Type::SIZE_TYPE size,
00936 const char*)
00937 {
00938 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
00939 const char* const nm = name->last_component()->get_string();
00940 struct_decls(name, size);
00941 be_global->lang_header_ <<
00942 "\n"
00943 "struct " << exporter() << nm << " \n"
00944 "{\n"
00945 " typedef " << nm << "_var _var_type;\n"
00946 " typedef " << nm << "_out _out_type;\n\n";
00947
00948 for (size_t i = 0; i < fields.size(); ++i) {
00949 AST_Type* field_type = fields[i]->field_type();
00950 const std::string field_name = fields[i]->local_name()->get_string();
00951 std::string type_name = map_type(field_type);
00952 const Classification cls = classify(field_type);
00953 if (cls & CL_STRING) {
00954 type_name = helpers_[(cls & CL_WIDE) ? HLP_WSTR_MGR : HLP_STR_MGR];
00955 }
00956 be_global->lang_header_ <<
00957 " " << type_name << ' ' << field_name << ";\n";
00958 }
00959
00960 be_global->lang_header_ << "\n"
00961 " bool operator==(const " << nm << "& rhs) const;\n"
00962 " bool operator!=(const " << nm << "& rhs) const { return !(*this == rhs); }\n"
00963 " OPENDDS_POOL_ALLOCATION_HOOKS\n"
00964 "};\n\n";
00965
00966 be_global->add_include("dds/DCPS/PoolAllocationBase.h", BE_GlobalData::STREAM_LANG_H);
00967 be_global->add_include("<ace/CDR_Stream.h>", BE_GlobalData::STREAM_LANG_H);
00968
00969 if (size == AST_Type::VARIABLE) {
00970 be_global->lang_header_ <<
00971 exporter() << "void swap(" << nm << "& lhs, " << nm << "& rhs);\n\n";
00972 }
00973
00974 be_global->lang_header_ <<
00975 exporter() << "ACE_CDR::Boolean operator<< (ACE_OutputCDR& os, const " << nm << "& x);\n\n";
00976 be_global->lang_header_ <<
00977 exporter() << "ACE_CDR::Boolean operator>> (ACE_InputCDR& os, " << nm << "& x);\n\n";
00978
00979 {
00980 const ScopedNamespaceGuard guard(name, be_global->impl_);
00981 be_global->impl_ <<
00982 "bool " << nm << "::operator==(const " << nm << "& rhs) const\n"
00983 "{\n";
00984 for (size_t i = 0; i < fields.size(); ++i) {
00985 const std::string field_name = fields[i]->local_name()->get_string();
00986 AST_Type* field_type = resolveActualType(fields[i]->field_type());
00987 const Classification cls = classify(field_type);
00988 if (cls & CL_ARRAY) {
00989 std::string indent(" ");
00990 NestedForLoops nfl("int", "i",
00991 AST_Array::narrow_from_decl(field_type), indent, true);
00992 be_global->impl_ <<
00993 indent << "if (" << field_name << nfl.index_ << " != rhs."
00994 << field_name << nfl.index_ << ") {\n" <<
00995 indent << " return false;\n" <<
00996 indent << "}\n";
00997 } else {
00998 be_global->impl_ <<
00999 " if (" << field_name << " != rhs." << field_name << ") {\n"
01000 " return false;\n"
01001 " }\n";
01002 }
01003 }
01004 be_global->impl_ << " return true;\n}\n\n";
01005
01006 if (size == AST_Type::VARIABLE) {
01007 be_global->impl_ <<
01008 "void swap(" << nm << "& lhs, " << nm << "& rhs)\n"
01009 "{\n"
01010 " using std::swap;\n";
01011 for (size_t i = 0; i < fields.size(); ++i) {
01012 const std::string fn = fields[i]->local_name()->get_string();
01013 AST_Type* field_type = resolveActualType(fields[i]->field_type());
01014 const Classification cls = classify(field_type);
01015 if (cls & CL_ARRAY) {
01016 ACE_CDR::ULong elems = 1;
01017 const std::string flat_fn = fn + array_dims(field_type, elems);
01018 be_global->add_include("<algorithm>", BE_GlobalData::STREAM_CPP);
01019 be_global->impl_ <<
01020 " std::swap_ranges(lhs." << flat_fn << ", lhs." << flat_fn
01021 << " + " << elems << ", rhs." << flat_fn << ");\n";
01022 } else {
01023 be_global->impl_ <<
01024 " swap(lhs." << fn << ", rhs." << fn << ");\n";
01025 }
01026 }
01027 be_global->impl_ << "}\n\n";
01028 }
01029
01030 be_global->impl_ <<
01031 "ACE_CDR::Boolean operator<< (ACE_OutputCDR &, const " << nm << "&) { return true; }\n\n";
01032 be_global->impl_ <<
01033 "ACE_CDR::Boolean operator>> (ACE_InputCDR &, " << nm << "&) { return true; }\n\n";
01034 }
01035
01036 gen_typecode(name);
01037 return true;
01038 }
01039
01040 static SafetyProfileGenerator instance;
01041 };
01042 SafetyProfileGenerator SafetyProfileGenerator::instance;
01043
01044 void langmap_generator::init()
01045 {
01046 switch (be_global->language_mapping()) {
01047 case BE_GlobalData::LANGMAP_FACE_CXX:
01048 generator_ = &FaceGenerator::instance;
01049 generator_->init();
01050 break;
01051 case BE_GlobalData::LANGMAP_SP_CXX:
01052 generator_ = &SafetyProfileGenerator::instance;
01053 generator_->init();
01054 break;
01055 default: break;
01056 }
01057 }
01058
01059 bool langmap_generator::gen_const(UTL_ScopedName* name, bool,
01060 AST_Constant* constant)
01061 {
01062 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
01063 const char* const nm = name->last_component()->get_string();
01064
01065 const AST_Expression::ExprType type = constant->et();
01066 const bool is_enum = (type == AST_Expression::EV_enum);
01067 const std::string type_name = is_enum
01068 ? scoped(constant->enum_full_name()) : map_type(type);
01069 be_global->lang_header_ <<
01070 "const " << type_name << ' ' << nm << " = ";
01071
01072 if (is_enum) {
01073 be_global->lang_header_ << scoped(constant->constant_value()->n()) << ";\n";
01074 } else {
01075 be_global->lang_header_ << *constant->constant_value()->ev() << ";\n";
01076 }
01077 return true;
01078 }
01079
01080 namespace {
01081 void gen_array(UTL_ScopedName* tdname, AST_Array* arr)
01082 {
01083 be_global->add_include("<tao/Array_VarOut_T.h>", BE_GlobalData::STREAM_LANG_H);
01084 be_global->add_include("dds/DCPS/SafetyProfilePool.h", BE_GlobalData::STREAM_LANG_H);
01085 const char* const nm = tdname->last_component()->get_string();
01086 AST_Type* elem = arr->base_type();
01087 const Classification elem_cls = classify(elem);
01088 const Helper var = (elem->size_type() == AST_Type::VARIABLE)
01089 ? HLP_ARR_VAR_VAR : HLP_ARR_FIX_VAR,
01090 out = HLP_ARR_OUT,
01091 forany = HLP_ARR_FORANY;
01092
01093 std::ostringstream bound, nofirst, total;
01094 std::string zeros;
01095 for (ACE_CDR::ULong dim = 0; dim < arr->n_dims(); ++dim) {
01096 const ACE_CDR::ULong extent = arr->dims()[dim]->ev()->u.ulval;
01097 bound << '[' << extent << ']';
01098 if (dim) {
01099 nofirst << '[' << extent << ']';
01100 zeros += "[0]";
01101 total << " * ";
01102 }
01103 total << extent;
01104 }
01105
01106 std::string elem_type = map_type(elem);
01107 if (elem_cls & CL_STRING) {
01108 elem_type = helpers_[(elem_cls & CL_WIDE) ? HLP_WSTR_MGR : HLP_STR_MGR];
01109 }
01110
01111 std::string out_type = nm;
01112 if (elem->size_type() == AST_Type::VARIABLE) {
01113 out_type = helpers_[out] + '<' + nm + ", " + nm + "_var, " + nm +
01114 "_slice, " + nm + "_tag>";
01115 }
01116
01117 be_global->lang_header_ <<
01118 "typedef " << elem_type << ' ' << nm << bound.str() << ";\n"
01119 "typedef " << elem_type << ' ' << nm << "_slice" << nofirst.str() << ";\n"
01120 "struct " << nm << "_tag {};\n"
01121 "typedef " << helpers_[var] << '<' << nm << ", " << nm << "_slice, "
01122 << nm << "_tag> " << nm << "_var;\n"
01123 "typedef " << out_type << ' ' << nm << "_out;\n"
01124 "typedef " << helpers_[forany] << '<' << nm << ", " << nm << "_slice, "
01125 << nm << "_tag> " << nm << "_forany;\n\n" <<
01126 exporter() << nm << "_slice* " << nm << "_alloc();\n" <<
01127 exporter() << "void " << nm << "_init_i(" << elem_type << "* begin);\n" <<
01128 exporter() << "void " << nm << "_fini_i(" << elem_type << "* begin);\n" <<
01129 exporter() << "void " << nm << "_free(" << nm << "_slice* slice);\n" <<
01130 exporter() << nm << "_slice* " << nm << "_dup(const " << nm
01131 << "_slice* slice);\n" <<
01132 exporter() << "void " << nm << "_copy(" << nm << "_slice* dst, const "
01133 << nm << "_slice* src);\n\n";
01134 const ScopedNamespaceGuard namespaces(tdname, be_global->impl_);
01135 be_global->impl_ <<
01136 nm << "_slice* " << nm << "_alloc()\n"
01137 "{\n"
01138 " void* const raw = ACE_Allocator::instance()->malloc"
01139 "(sizeof(" << nm << "));\n"
01140 " " << nm << "_slice* const slice = static_cast<" << nm << "_slice*"
01141 << ">(raw);\n"
01142 " " << nm << "_init_i(slice" << zeros << ");\n"
01143 " return slice;\n"
01144 "}\n\n"
01145 "void " << nm << "_init_i(" << elem_type << "* begin)\n"
01146 "{\n";
01147
01148 if (elem_cls & (CL_PRIMITIVE | CL_ENUM)) {
01149 be_global->impl_ << " ACE_UNUSED_ARG(begin);\n";
01150 } else if (elem_cls & CL_ARRAY) {
01151 std::string indent = " ";
01152 const NestedForLoops nfl("ACE_CDR::ULong", "i", arr, indent);
01153 be_global->impl_ <<
01154 indent << elem_type << "_init_i(begin" << nfl.index_ << ");\n";
01155 } else {
01156 be_global->impl_ <<
01157 " std::uninitialized_fill_n(begin, " << total.str() << ", "
01158 << elem_type << "());\n";
01159 }
01160
01161 be_global->impl_ <<
01162 "}\n\n"
01163 "void " << nm << "_fini_i(" << elem_type << "* begin)\n"
01164 "{\n";
01165
01166 if (elem_cls & (CL_PRIMITIVE | CL_ENUM)) {
01167 be_global->impl_ << " ACE_UNUSED_ARG(begin);\n";
01168 } else if (elem_cls & CL_ARRAY) {
01169 std::string indent = " ";
01170 const NestedForLoops nfl("ACE_CDR::ULong", "i", arr, indent);
01171 be_global->impl_ <<
01172 indent << elem_type << "_fini_i(begin" << nfl.index_ << ");\n";
01173 } else {
01174 const std::string::size_type idx_last = elem_type.rfind("::");
01175 const std::string elem_last =
01176 (elem_cls & CL_STRING) ? "StringManager" :
01177 ((idx_last == std::string::npos) ? elem_type
01178 : elem_type.substr(idx_last + 2));
01179 be_global->impl_ <<
01180 " for (int i = 0; i < " << total.str() << "; ++i) {\n"
01181 " begin[i]."
01182 #ifdef __SUNPRO_CC
01183 << elem_type << "::"
01184 #endif
01185 "~" << elem_last << "();\n"
01186 " }\n";
01187 }
01188
01189 be_global->impl_ <<
01190 "}\n\n"
01191 "void " << nm << "_free(" << nm << "_slice* slice)\n"
01192 "{\n"
01193 " if (!slice) return;\n"
01194 " " << nm << "_fini_i(slice" << zeros << ");\n"
01195 " ACE_Allocator::instance()->free(slice);\n"
01196 "}\n\n" <<
01197 nm << "_slice* " << nm << "_dup(const " << nm << "_slice* slice)\n"
01198 "{\n"
01199 " " << nm << "_slice* const arr = " << nm << "_alloc();\n"
01200 " if (arr) " << nm << "_copy(arr, slice);\n"
01201 " return arr;\n"
01202 "}\n\n"
01203 "void " << nm << "_copy(" << nm << "_slice* dst, const " << nm
01204 << "_slice* src)\n"
01205 "{\n"
01206 " if (!src || !dst) return;\n";
01207
01208 {
01209 std::string indent = " ";
01210 const NestedForLoops nfl("ACE_CDR::ULong", "i", arr, indent);
01211 if (elem_cls & CL_ARRAY) {
01212 be_global->impl_ <<
01213 indent << elem_type << "_copy(dst" << nfl.index_ << ", src"
01214 << nfl.index_ << ");\n";
01215 } else {
01216 be_global->impl_ <<
01217 indent << "dst" << nfl.index_ << " = src" << nfl.index_ << ";\n";
01218 }
01219 }
01220
01221 be_global->impl_ <<
01222 "}\n\n";
01223
01224
01225 be_global->lang_header_ <<
01226 "inline ACE_CDR::Boolean operator<<(ACE_OutputCDR &, const " << nm << "_forany&) { return true; }\n\n"
01227 "inline ACE_CDR::Boolean operator>>(ACE_InputCDR &, " << nm << "_forany&) { return true; }\n\n";
01228 }
01229 }
01230
01231 bool langmap_generator::gen_enum(AST_Enum*, UTL_ScopedName* name,
01232 const std::vector<AST_EnumVal*>& contents,
01233 const char*)
01234 {
01235 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
01236 const char* const nm = name->last_component()->get_string();
01237 be_global->lang_header_ <<
01238 "enum " << nm << " {\n";
01239 for (size_t i = 0; i < contents.size(); ++i) {
01240 be_global->lang_header_ <<
01241 " " << contents[i]->local_name()->get_string()
01242 << ((i < contents.size() - 1) ? ",\n" : "\n");
01243 }
01244 be_global->lang_header_ <<
01245 "};\n\n"
01246 "typedef " << nm << "& " << nm << "_out;\n";
01247 gen_typecode(name);
01248 return true;
01249 }
01250
01251 bool langmap_generator::gen_struct_fwd(UTL_ScopedName* name,
01252 AST_Type::SIZE_TYPE size)
01253 {
01254 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
01255 struct_decls(name, size);
01256 return true;
01257 }
01258
01259 bool langmap_generator::gen_struct(AST_Structure* s, UTL_ScopedName* name,
01260 const std::vector<AST_Field*>& fields,
01261 AST_Type::SIZE_TYPE size,
01262 const char* x)
01263 {
01264 return generator_->gen_struct(s, name, fields, size, x);
01265 }
01266
01267 namespace {
01268
01269
01270
01271 void gen_array_traits(UTL_ScopedName* tdname, AST_Array* arr)
01272 {
01273 const std::string nm = scoped(tdname);
01274 std::string zeros;
01275 for (ACE_CDR::ULong i = 1; i < arr->n_dims(); ++i) zeros += "[0]";
01276 be_global->lang_header_ <<
01277 "TAO_BEGIN_VERSIONED_NAMESPACE_DECL\nnamespace TAO {\n"
01278 "template <>\n"
01279 "struct " << exporter() << "Array_Traits<" << nm << "_forany>\n"
01280 "{\n"
01281 " static void free(" << nm << "_slice* slice)\n"
01282 " {\n"
01283 " " << nm << "_free(slice);\n"
01284 " }\n\n"
01285 " static " << nm << "_slice* dup(const " << nm << "_slice* slice)\n"
01286 " {\n"
01287 " return " << nm << "_dup(slice);\n"
01288 " }\n\n"
01289 " static void copy(" << nm << "_slice* dst, const " << nm
01290 << "_slice* src)\n"
01291 " {\n"
01292 " " << nm << "_copy(dst, src);\n"
01293 " }\n\n"
01294 " static " << nm << "_slice* alloc()\n"
01295 " {\n"
01296 " return " << nm << "_alloc();\n"
01297 " }\n\n"
01298 " static void zero(" << nm << "_slice* slice)\n"
01299 " {\n"
01300 " " << nm << "_fini_i(slice" << zeros << ");\n"
01301 " " << nm << "_init_i(slice" << zeros << ");\n"
01302 " }\n"
01303 " static void construct(" << nm << "_slice* slice)\n"
01304 " {\n"
01305 " " << nm << "_init_i(slice" << zeros << ");\n"
01306 " }\n"
01307 " static void destroy(" << nm << "_slice* slice)\n"
01308 " {\n"
01309 " " << nm << "_fini_i(slice" << zeros << ");\n"
01310 " }\n"
01311 "};\n}\nTAO_END_VERSIONED_NAMESPACE_DECL\n\n";
01312 }
01313
01314 #ifdef ACE_HAS_CDR_FIXED
01315 void gen_fixed(UTL_ScopedName* name, AST_Fixed* fixed)
01316 {
01317 be_global->add_include("FACE/Fixed.h", BE_GlobalData::STREAM_LANG_H);
01318 const char* const nm = name->last_component()->get_string();
01319 be_global->lang_header_ <<
01320 "typedef " << helpers_[HLP_FIXED] << '<' << *fixed->digits()->ev()
01321 << ", " << *fixed->scale()->ev() << "> " << nm << ";\n"
01322 "typedef " << nm << "& " << nm << "_out;\n";
01323 }
01324 #endif
01325 }
01326
01327 bool langmap_generator::gen_typedef(AST_Typedef*, UTL_ScopedName* name, AST_Type* base,
01328 const char*)
01329 {
01330 AST_Array* arr = 0;
01331 {
01332 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
01333 const char* const nm = name->last_component()->get_string();
01334
01335 const Classification cls = classify(base);
01336
01337 switch (base->node_type()) {
01338 case AST_Decl::NT_sequence:
01339 generator_->gen_sequence(name, AST_Sequence::narrow_from_decl(base));
01340 break;
01341 case AST_Decl::NT_array:
01342 gen_array(name, arr = AST_Array::narrow_from_decl(base));
01343 break;
01344 case AST_Decl::NT_fixed:
01345 # ifdef ACE_HAS_CDR_FIXED
01346 gen_fixed(name, AST_Fixed::narrow_from_decl(base));
01347 break;
01348 # else
01349 std::cerr << "ERROR: fixed data type (for " << nm << ") is not supported"
01350 " with this version of ACE+TAO\n";
01351 return false;
01352 # endif
01353 default:
01354 be_global->lang_header_ <<
01355 "typedef " << map_type(base) << ' ' << nm << ";\n";
01356 if ((cls & CL_STRING) == 0) {
01357 be_global->lang_header_ <<
01358 "typedef " << map_type(base) << "_out " << nm << "_out;\n";
01359 }
01360
01361 AST_Type* actual_base = resolveActualType(base);
01362 if (actual_base->node_type() == AST_Decl::NT_array) {
01363 be_global->lang_header_ <<
01364 "typedef " << map_type(base) << "_var " << nm << "_var;\n" <<
01365 "typedef " << map_type(base) << "_slice " << nm << "_slice;\n" <<
01366 "typedef " << map_type(base) << "_forany " << nm << "_forany;\n\n" <<
01367 "inline " << nm << "_slice *" << nm << "_alloc() { return " << map_type(base) << "_alloc(); }\n" <<
01368 "inline " << nm << "_slice* " << nm << "_dup(" << nm << "_slice *a) { return " << map_type(base) << "_dup(a); }\n" <<
01369 "inline void " << nm << "_copy(" << nm << "_slice* to, const " << nm << "_slice* from) { " << map_type(base) << "_copy(to, from); }\n" <<
01370 "inline void " << nm << "_free(" << nm << "_slice *a) { " << map_type(base) << "_free(a); }\n";
01371 }
01372
01373 break;
01374 }
01375
01376 if (cls & CL_STRING) {
01377 const Helper var = (cls & CL_WIDE) ? HLP_WSTR_VAR : HLP_STR_VAR,
01378 out = (cls & CL_WIDE) ? HLP_WSTR_OUT : HLP_STR_OUT;
01379 be_global->lang_header_ <<
01380 "typedef " << helpers_[var] << ' ' << nm << "_var;\n"
01381 "typedef " << helpers_[out] << ' ' << nm << "_out;\n";
01382 }
01383
01384 gen_typecode(name);
01385 }
01386 if (arr) gen_array_traits(name, arr);
01387 return true;
01388 }
01389
01390 bool langmap_generator::gen_union_fwd(AST_UnionFwd* node,
01391 UTL_ScopedName* name,
01392 AST_Type::SIZE_TYPE)
01393 {
01394 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
01395 struct_decls(name, node->full_definition()->size_type());
01396 return true;
01397 }
01398
01399 bool langmap_generator::gen_union(AST_Union* u, UTL_ScopedName* name,
01400 const std::vector<AST_UnionBranch*>& branches,
01401 AST_Type* discriminator,
01402 const char*)
01403 {
01404 return generator_->gen_union(u, name, branches, discriminator);
01405 }
01406
01407 bool langmap_generator::gen_interf_fwd(UTL_ScopedName* name)
01408 {
01409 const ScopedNamespaceGuard namespaces(name, be_global->lang_header_);
01410
01411 be_global->add_include("<tao/Objref_VarOut_T.h>", BE_GlobalData::STREAM_LANG_H);
01412 const char* const nm = name->last_component()->get_string();
01413 be_global->lang_header_ <<
01414 "class " << nm << ";\n"
01415 "typedef " << nm << '*' << nm << "_ptr;\n"
01416 "typedef TAO_Objref_Var_T<" << nm << "> " << nm << "_var;\n"
01417 "typedef TAO_Objref_Out_T<" << nm << "> " << nm << "_out;\n";
01418
01419 return true;
01420 }