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