dds_generator.h

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef dds_generator_H
00009 #define dds_generator_H
00010 
00011 #include "be_extern.h"
00012 
00013 #include "utl_scoped_name.h"
00014 #include "utl_identifier.h"
00015 #include "utl_string.h"
00016 
00017 #include "ast.h"
00018 #include "ast_component_fwd.h"
00019 #include "ast_eventtype_fwd.h"
00020 #include "ast_structure_fwd.h"
00021 #include "ast_union_fwd.h"
00022 #include "ast_valuetype_fwd.h"
00023 
00024 #include "ace/CDR_Base.h"
00025 
00026 #include <string>
00027 #include <vector>
00028 #include <cstring>
00029 
00030 #include "../DCPS/RestoreOutputStreamState.h"
00031 
00032 class dds_generator {
00033 public:
00034   virtual ~dds_generator() = 0;
00035 
00036   virtual bool do_included_files() const { return false; }
00037 
00038   virtual void gen_prologue() {}
00039 
00040   virtual void gen_epilogue() {}
00041 
00042   virtual bool gen_const(UTL_ScopedName* /*name*/,
00043                          bool /*nestedInInteface*/,
00044                          AST_Constant* /*constant*/)
00045   { return true; }
00046 
00047   virtual bool gen_enum(AST_Enum* /*node*/, UTL_ScopedName* /*name*/,
00048                         const std::vector<AST_EnumVal*>& /*contents*/,
00049                         const char* /*repoid*/)
00050   { return true; }
00051 
00052   virtual bool gen_struct(AST_Structure* node, UTL_ScopedName* name,
00053                           const std::vector<AST_Field*>& fields,
00054                           AST_Type::SIZE_TYPE size,
00055                           const char* repoid) = 0;
00056 
00057   virtual bool gen_struct_fwd(UTL_ScopedName* /*name*/,
00058                               AST_Type::SIZE_TYPE /*size*/)
00059   { return true; }
00060 
00061   virtual bool gen_typedef(AST_Typedef* node, UTL_ScopedName* name, AST_Type* base,
00062                            const char* repoid) = 0;
00063 
00064   virtual bool gen_interf(AST_Interface* /*node*/, UTL_ScopedName* /*name*/, bool /*local*/,
00065                           const std::vector<AST_Interface*>& /*inherits*/,
00066                           const std::vector<AST_Interface*>& /*inherits_flat*/,
00067                           const std::vector<AST_Attribute*>& /*attrs*/,
00068                           const std::vector<AST_Operation*>& /*ops*/,
00069                           const char* /*repoid*/)
00070   { return true; }
00071 
00072   virtual bool gen_interf_fwd(UTL_ScopedName* /*name*/)
00073   { return true; }
00074 
00075   virtual bool gen_native(AST_Native* /*node*/, UTL_ScopedName* /*name*/, const char* /*repoid*/)
00076   { return true; }
00077 
00078   virtual bool gen_union(AST_Union* node, UTL_ScopedName* name,
00079                          const std::vector<AST_UnionBranch*>& branches,
00080                          AST_Type* discriminator,
00081                          const char* repoid) = 0;
00082 
00083   virtual bool gen_union_fwd(AST_UnionFwd* /*node*/, UTL_ScopedName* /*name*/,
00084                              AST_Type::SIZE_TYPE /*size*/)
00085   { return true; }
00086 
00087   static std::string scoped_helper(UTL_ScopedName* sn, const char* sep);
00088   static std::string module_scope_helper(UTL_ScopedName* sn, const char* sep);
00089 };
00090 
00091 class composite_generator : public dds_generator {
00092 public:
00093   void gen_prologue();
00094 
00095   void gen_epilogue();
00096 
00097   bool gen_const(UTL_ScopedName* name, bool nestedInInteface,
00098                  AST_Constant* constant);
00099 
00100   bool gen_enum(AST_Enum* node, UTL_ScopedName* name,
00101                 const std::vector<AST_EnumVal*>& contents, const char* repoid);
00102 
00103   bool gen_struct(AST_Structure* node, UTL_ScopedName* name,
00104                   const std::vector<AST_Field*>& fields,
00105                   AST_Type::SIZE_TYPE size, const char* repoid);
00106 
00107   bool gen_struct_fwd(UTL_ScopedName* name, AST_Type::SIZE_TYPE size);
00108 
00109   bool gen_typedef(AST_Typedef* node, UTL_ScopedName* name, AST_Type* base, const char* repoid);
00110 
00111   bool gen_interf(AST_Interface* node, UTL_ScopedName* name, bool local,
00112                   const std::vector<AST_Interface*>& inherits,
00113                   const std::vector<AST_Interface*>& inherits_flat,
00114                   const std::vector<AST_Attribute*>& attrs,
00115                   const std::vector<AST_Operation*>& ops, const char* repoid);
00116 
00117   bool gen_interf_fwd(UTL_ScopedName* name);
00118 
00119   bool gen_native(AST_Native* node, UTL_ScopedName* name, const char* repoid);
00120 
00121   bool gen_union(AST_Union* node, UTL_ScopedName* name,
00122                  const std::vector<AST_UnionBranch*>& branches,
00123                  AST_Type* discriminator,
00124                  const char* repoid);
00125 
00126   bool gen_union_fwd(AST_UnionFwd*, UTL_ScopedName* name, AST_Type::SIZE_TYPE size);
00127 
00128   template <typename InputIterator>
00129   composite_generator(InputIterator begin, InputIterator end)
00130   : components_(begin, end) {}
00131 
00132   void add_generator(dds_generator* gen) { components_.push_back(gen); }
00133 
00134 private:
00135   std::vector<dds_generator*> components_;
00136 };
00137 
00138 // common utilities for all "generator" derived classes
00139 
00140 struct NamespaceGuard {
00141   NamespaceGuard()
00142   {
00143     be_global->header_ << "OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL\nnamespace OpenDDS { namespace DCPS {\n\n";
00144     be_global->impl_ << "OPENDDS_BEGIN_VERSIONED_NAMESPACE_DECL\nnamespace OpenDDS { namespace DCPS {\n\n";
00145   }
00146   ~NamespaceGuard()
00147   {
00148     be_global->header_ << "}  }\nOPENDDS_END_VERSIONED_NAMESPACE_DECL\n\n";
00149     be_global->impl_ << "}  }\nOPENDDS_END_VERSIONED_NAMESPACE_DECL\n\n";
00150   }
00151 };
00152 
00153 struct ScopedNamespaceGuard  {
00154   ScopedNamespaceGuard(UTL_ScopedName* name, std::ostream& os,
00155                        const char* keyword = "namespace")
00156     : os_(os)
00157   {
00158     for (n_ = 0; name->tail();
00159          name = static_cast<UTL_ScopedName*>(name->tail())) {
00160       const char* str = name->head()->get_string();
00161       if (str && str[0]) {
00162         ++n_;
00163         os << keyword << (name->head()->escaped() ? " _" : " ")
00164            << str << " {\n";
00165       }
00166     }
00167     if (std::strcmp(keyword, "module") == 0) semi_ = ";";
00168   }
00169 
00170   ~ScopedNamespaceGuard()
00171   {
00172     for (int i = 0; i < n_; ++i) os_ << '}' << semi_ << '\n';
00173   }
00174 
00175   std::ostream& os_;
00176   std::string semi_;
00177   int n_;
00178 };
00179 
00180 struct Function {
00181   bool has_arg_;
00182   std::string preamble_;
00183 
00184   Function(const char* name, const char* returntype)
00185     : has_arg_(false)
00186   {
00187     using std::string;
00188     ACE_CString ace_exporter = be_global->export_macro();
00189     bool use_exp = ace_exporter != "";
00190     string exporter = use_exp ? (string(" ") + ace_exporter.c_str()) : "";
00191     be_global->header_ << ace_exporter << (use_exp ? "\n" : "")
00192       << returntype << " " << name << "(";
00193     be_global->impl_ << returntype << " " << name << "(";
00194   }
00195 
00196   void addArg(const char* name, const std::string& type)
00197   {
00198     std::string sig = (has_arg_ ? ", " : "") + type + (name[0] ? " " : "")
00199       + (name[0] ? name : "");
00200     be_global->header_ << sig;
00201     be_global->impl_ << sig;
00202     if (name[0]) {
00203       preamble_ += "  ACE_UNUSED_ARG(" + std::string(name) + ");\n";
00204     }
00205     has_arg_ = true;
00206   }
00207 
00208   void endArgs()
00209   {
00210     be_global->header_ << ");\n\n";
00211     be_global->impl_ << ")\n{\n" << preamble_;
00212   }
00213 
00214   ~Function()
00215   {
00216     be_global->impl_ << "}\n\n";
00217   }
00218 };
00219 
00220 inline std::string scoped(UTL_ScopedName* sn)
00221 {
00222   return dds_generator::scoped_helper(sn, "::");
00223 }
00224 
00225 inline std::string module_scope(UTL_ScopedName* sn)
00226 {
00227   return dds_generator::module_scope_helper(sn, "::");
00228 }
00229 
00230 namespace AstTypeClassification {
00231   inline AST_Type* resolveActualType(AST_Type* element)
00232   {
00233     if (element->node_type() == AST_Decl::NT_typedef) {
00234       AST_Typedef* td = AST_Typedef::narrow_from_decl(element);
00235       return td->primitive_base_type();
00236     }
00237 
00238     switch(element->node_type()) {
00239     case AST_Decl::NT_interface_fwd:
00240     {
00241       AST_InterfaceFwd* td = AST_InterfaceFwd::narrow_from_decl(element);
00242       return td->full_definition();
00243     }
00244     case AST_Decl::NT_valuetype_fwd:
00245     {
00246       AST_ValueTypeFwd* td = AST_ValueTypeFwd::narrow_from_decl(element);
00247       return td->full_definition();
00248     }
00249     case AST_Decl::NT_union_fwd:
00250     {
00251       AST_UnionFwd* td = AST_UnionFwd::narrow_from_decl(element);
00252       return td->full_definition();
00253     }
00254     case AST_Decl::NT_struct_fwd:
00255     {
00256       AST_StructureFwd* td = AST_StructureFwd::narrow_from_decl(element);
00257       return td->full_definition();
00258     }
00259     case AST_Decl::NT_component_fwd:
00260     {
00261       AST_ComponentFwd* td = AST_ComponentFwd::narrow_from_decl(element);
00262       return td->full_definition();
00263     }
00264     case AST_Decl::NT_eventtype_fwd:
00265     {
00266       AST_EventTypeFwd* td = AST_EventTypeFwd::narrow_from_decl(element);
00267       return td->full_definition();
00268     }
00269     default:
00270       return element;
00271     }
00272   }
00273 
00274   typedef size_t Classification;
00275   const Classification CL_UNKNOWN = 0, CL_SCALAR = 1, CL_PRIMITIVE = 2,
00276     CL_STRUCTURE = 4, CL_STRING = 8, CL_ENUM = 16, CL_UNION = 32, CL_ARRAY = 64,
00277     CL_SEQUENCE = 128, CL_WIDE = 256, CL_BOUNDED = 512, CL_INTERFACE = 1024,
00278     CL_FIXED = 2048;
00279 
00280   inline Classification classify(AST_Type* type)
00281   {
00282     type = AstTypeClassification::resolveActualType(type);
00283     switch (type->node_type()) {
00284     case AST_Decl::NT_pre_defined: {
00285       AST_PredefinedType* p = AST_PredefinedType::narrow_from_decl(type);
00286       switch (p->pt()) {
00287       case AST_PredefinedType::PT_any:
00288       case AST_PredefinedType::PT_object:
00289         return CL_UNKNOWN;
00290       case AST_PredefinedType::PT_wchar:
00291         return CL_SCALAR | CL_PRIMITIVE | CL_WIDE;
00292       default:
00293         return CL_SCALAR | CL_PRIMITIVE;
00294       }
00295     }
00296     case AST_Decl::NT_array:
00297       return CL_ARRAY;
00298     case AST_Decl::NT_union:
00299       return CL_UNION;
00300     case AST_Decl::NT_string:
00301     case AST_Decl::NT_wstring:
00302       return CL_SCALAR | CL_STRING |
00303         ((AST_String::narrow_from_decl(type)->max_size()->ev()->u.ulval == 0)
00304         ? 0 : CL_BOUNDED) |
00305         ((type->node_type() == AST_Decl::NT_wstring) ? CL_WIDE : 0);
00306     case AST_Decl::NT_sequence:
00307       return CL_SEQUENCE |
00308         ((AST_Sequence::narrow_from_decl(type)->unbounded()) ? 0 : CL_BOUNDED);
00309     case AST_Decl::NT_struct:
00310       return CL_STRUCTURE;
00311     case AST_Decl::NT_enum:
00312       return CL_SCALAR | CL_ENUM;
00313     case AST_Decl::NT_interface:
00314       return CL_INTERFACE;
00315 #ifdef ACE_HAS_CDR_FIXED
00316     case AST_Decl::NT_fixed:
00317       return CL_FIXED;
00318 #endif
00319     default:
00320       return CL_UNKNOWN;
00321     }
00322   }
00323 }
00324 
00325 struct NestedForLoops {
00326   NestedForLoops(const char* type, const char* prefix, AST_Array* arr,
00327                  std::string& indent, bool followTypedefs = false);
00328   ~NestedForLoops();
00329 
00330   size_t n_;
00331   std::string& indent_;
00332   std::string index_;
00333 };
00334 
00335 enum WrapDirection {WD_OUTPUT, WD_INPUT};
00336 
00337 inline
00338 std::string wrapPrefix(AST_Type* type, WrapDirection wd)
00339 {
00340   switch (type->node_type()) {
00341   case AST_Decl::NT_pre_defined: {
00342     AST_PredefinedType* p = AST_PredefinedType::narrow_from_decl(type);
00343     switch (p->pt()) {
00344     case AST_PredefinedType::PT_char:
00345       return (wd == WD_OUTPUT)
00346         ? "ACE_OutputCDR::from_char(" : "ACE_InputCDR::to_char(";
00347     case AST_PredefinedType::PT_wchar:
00348       return (wd == WD_OUTPUT)
00349         ? "ACE_OutputCDR::from_wchar(" : "ACE_InputCDR::to_wchar(";
00350     case AST_PredefinedType::PT_octet:
00351       return (wd == WD_OUTPUT)
00352         ? "ACE_OutputCDR::from_octet(" : "ACE_InputCDR::to_octet(";
00353     case AST_PredefinedType::PT_boolean:
00354       return (wd == WD_OUTPUT)
00355         ? "ACE_OutputCDR::from_boolean(" : "ACE_InputCDR::to_boolean(";
00356     default:
00357       return "";
00358     }
00359   }
00360   case AST_Decl::NT_string:
00361     return (wd == WD_OUTPUT)
00362       ? "ACE_OutputCDR::from_string(" : "ACE_InputCDR::to_string(";
00363   case AST_Decl::NT_wstring:
00364     return (wd == WD_OUTPUT)
00365       ? "ACE_OutputCDR::from_wstring(" : "ACE_InputCDR::to_wstring(";
00366   default:
00367     return "";
00368   }
00369 }
00370 
00371 inline
00372 std::string getWrapper(const std::string& name, AST_Type* type, WrapDirection wd)
00373 {
00374   std::string pre = wrapPrefix(type, wd);
00375   return (pre.empty()) ? name : (pre + name + ')');
00376 }
00377 
00378 inline
00379 std::string getEnumLabel(AST_Expression* label_val, AST_Type* disc)
00380 {
00381   std::string e = scoped(disc->name()),
00382     label = label_val->n()->last_component()->get_string();
00383   const size_t colon = e.rfind("::");
00384   if (colon == std::string::npos) {
00385     return label;
00386   }
00387   return e.replace(colon + 2, std::string::npos, label);
00388 }
00389 
00390 inline
00391 std::ostream& operator<<(std::ostream& o,
00392                          const AST_Expression::AST_ExprValue& ev)
00393 {
00394   OpenDDS::DCPS::RestoreOutputStreamState ross(o);
00395   switch (ev.et) {
00396   case AST_Expression::EV_octet:
00397     return o << static_cast<int>(ev.u.oval);
00398   case AST_Expression::EV_short:
00399     return o << ev.u.sval;
00400   case AST_Expression::EV_ushort:
00401     return o << ev.u.usval << 'u';
00402   case AST_Expression::EV_long:
00403     return o << ev.u.lval;
00404   case AST_Expression::EV_ulong:
00405     return o << ev.u.ulval << 'u';
00406   case AST_Expression::EV_longlong:
00407     return o << ev.u.llval << "LL";
00408   case AST_Expression::EV_ulonglong:
00409     return o << ev.u.ullval << "ULL";
00410   case AST_Expression::EV_wchar:
00411     return o << "L'" << static_cast<char>(ev.u.wcval) << '\'';
00412   case AST_Expression::EV_char:
00413     return o << '\'' << ev.u.cval << '\'';
00414   case AST_Expression::EV_bool:
00415     return o << std::boolalpha << static_cast<bool>(ev.u.bval);
00416   case AST_Expression::EV_float:
00417     return o << ev.u.fval << 'f';
00418   case AST_Expression::EV_double:
00419     return o << ev.u.dval;
00420   case AST_Expression::EV_wstring:
00421     return o << "L\"" << ev.u.wstrval << '"';
00422   case AST_Expression::EV_string:
00423     return o << '"' << ev.u.strval->get_string() << '"';
00424 #ifdef ACE_HAS_CDR_FIXED
00425   case AST_Expression::EV_fixed: {
00426     char buf[ACE_CDR::Fixed::MAX_STRING_SIZE];
00427     ev.u.fixedval.to_string(buf, sizeof buf);
00428     return o << "\"" << buf << "\"";
00429   }
00430 #endif
00431   default:
00432     return o;
00433   }
00434 }
00435 
00436 inline
00437 void generateBranchLabels(AST_UnionBranch* branch, AST_Type* discriminator,
00438                           size_t& n_labels, bool& has_default)
00439 {
00440   for (unsigned long j = 0; j < branch->label_list_length(); ++j) {
00441     ++n_labels;
00442     AST_UnionLabel* label = branch->label(j);
00443     if (label->label_kind() == AST_UnionLabel::UL_default) {
00444       be_global->impl_ << "  default:";
00445       has_default = true;
00446     } else if (discriminator->node_type() == AST_Decl::NT_enum) {
00447       be_global->impl_ << "  case "
00448         << getEnumLabel(label->label_val(), discriminator) << ':';
00449     } else {
00450       be_global->impl_ << "  case " << *label->label_val()->ev() << ':';
00451     }
00452     be_global->impl_<< ((j == branch->label_list_length() - 1) ? " {\n" : "\n");
00453   }
00454 }
00455 
00456 // see TAO_IDL_BE be_union::gen_empty_default_label()
00457 inline bool needSyntheticDefault(AST_Type* disc, size_t n_labels)
00458 {
00459   AST_Decl::NodeType nt = disc->node_type();
00460   if (nt == AST_Decl::NT_enum) return true;
00461 
00462   AST_PredefinedType* pdt = AST_PredefinedType::narrow_from_decl(disc);
00463   switch (pdt->pt()) {
00464   case AST_PredefinedType::PT_boolean:
00465     return n_labels < 2;
00466   case AST_PredefinedType::PT_char:
00467     return n_labels < ACE_OCTET_MAX;
00468   case AST_PredefinedType::PT_short:
00469   case AST_PredefinedType::PT_ushort:
00470     return n_labels < ACE_UINT16_MAX;
00471   case AST_PredefinedType::PT_long:
00472   case AST_PredefinedType::PT_ulong:
00473     return n_labels < ACE_UINT32_MAX;
00474   default:
00475     return true;
00476   }
00477 }
00478 
00479 typedef std::string (*CommonFn)(const std::string& name, AST_Type* type,
00480                                 const std::string& prefix, std::string& intro,
00481                                 const std::string&);
00482 
00483 inline
00484 void generateCaseBody(CommonFn commonFn, AST_UnionBranch* branch,
00485                       const char* statementPrefix, const char* namePrefix,
00486                       const char* uni, bool generateBreaks, bool parens)
00487 {
00488   using namespace AstTypeClassification;
00489   std::string intro, name = branch->local_name()->get_string();
00490   if (namePrefix == std::string(">> ")) {
00491     std::string brType = scoped(branch->field_type()->name()), forany;
00492     AST_Type* br = resolveActualType(branch->field_type());
00493     Classification br_cls = classify(br);
00494     if (!br->in_main_file()
00495         && br->node_type() != AST_Decl::NT_pre_defined) {
00496       be_global->add_referenced(br->file_name().c_str());
00497     }
00498     std::string rhs;
00499     if (br_cls & CL_STRING) {
00500       if (be_global->language_mapping() == BE_GlobalData::LANGMAP_FACE_CXX) {
00501         brType = std::string("FACE::") + ((br_cls & CL_WIDE) ? "W" : "")
00502           + "String_var";
00503       } else {
00504         brType = std::string("CORBA::") + ((br_cls & CL_WIDE) ? "W" : "")
00505           + "String_var";
00506       }
00507       rhs = "tmp.out()";
00508     } else if (br_cls & CL_ARRAY) {
00509       forany = "    " + brType + "_forany fa = tmp;\n";
00510       rhs = getWrapper("fa", br, WD_INPUT);
00511     } else {
00512       rhs = getWrapper("tmp", br, WD_INPUT);
00513     }
00514     be_global->impl_ <<
00515       "    " << brType << " tmp;\n" << forany <<
00516       "    if (strm >> " << rhs << ") {\n"
00517       "      uni." << name << "(tmp);\n"
00518       "      uni._d(disc);\n"
00519       "      return true;\n"
00520       "    }\n"
00521       "    return false;\n";
00522   } else {
00523     const char* breakString = generateBreaks ? "    break;\n" : "";
00524 
00525     std::string expr = commonFn(name + (parens ? "()" : ""), branch->field_type(),
00526                                 std::string(namePrefix) + "uni", intro, uni);
00527     be_global->impl_ <<
00528       (intro.empty() ? "" : "  ") << intro;
00529     if (*statementPrefix) {
00530       be_global->impl_ <<
00531         "    " << statementPrefix << " " << expr << ";\n" <<
00532         (statementPrefix == std::string("return") ? "" : breakString);
00533     } else {
00534       be_global->impl_ << expr << breakString;
00535     }
00536   }
00537 }
00538 
00539 inline
00540 bool generateSwitchBody(CommonFn commonFn,
00541                         const std::vector<AST_UnionBranch*>& branches,
00542                         AST_Type* discriminator, const char* statementPrefix,
00543                         const char* namePrefix = "", const char* uni = "",
00544                         bool forceDisableDefault = false, bool parens = true,
00545                         bool breaks = true)
00546 {
00547   size_t n_labels = 0;
00548   bool has_default = false;
00549   for (size_t i = 0; i < branches.size(); ++i) {
00550     AST_UnionBranch* branch = branches[i];
00551     if (forceDisableDefault) {
00552       bool foundDefault = false;
00553       for (unsigned long j = 0; j < branch->label_list_length(); ++j) {
00554         if (branch->label(j)->label_kind() == AST_UnionLabel::UL_default) {
00555           foundDefault = true;
00556         }
00557       }
00558       if (foundDefault) {
00559         has_default = true;
00560         continue;
00561       }
00562     }
00563     generateBranchLabels(branch, discriminator, n_labels, has_default);
00564     generateCaseBody(commonFn, branch, statementPrefix, namePrefix, uni, breaks, parens);
00565     be_global->impl_ <<
00566       "  }\n";
00567   }
00568   if (!has_default && needSyntheticDefault(discriminator, n_labels)) {
00569     be_global->impl_ <<
00570       "  default:\n" <<
00571       ((namePrefix == std::string(">> ")) ? "    uni._d(disc);\n" : "") <<
00572       "    break;\n";
00573     return true;
00574   }
00575   return false;
00576 }
00577 
00578 /// returns true if a default: branch was generated (no default: label in IDL)
00579 inline
00580 bool generateSwitchForUnion(const char* switchExpr, CommonFn commonFn,
00581                             const std::vector<AST_UnionBranch*>& branches,
00582                             AST_Type* discriminator, const char* statementPrefix,
00583                             const char* namePrefix = "", const char* uni = "",
00584                             bool forceDisableDefault = false, bool parens = true,
00585                             bool breaks = true)
00586 {
00587   using namespace AstTypeClassification;
00588   AST_Type* dt = resolveActualType(discriminator);
00589   AST_PredefinedType* bt = AST_PredefinedType::narrow_from_decl(dt);
00590   if (bt && bt->pt() == AST_PredefinedType::PT_boolean) {
00591     AST_UnionBranch* true_branch = 0;
00592     AST_UnionBranch* false_branch = 0;
00593     AST_UnionBranch* default_branch = 0;
00594     for (std::vector<AST_UnionBranch*>::const_iterator pos = branches.begin(),
00595          limit = branches.end(); pos != limit; ++pos) {
00596       AST_UnionBranch* branch = *pos;
00597       for (unsigned long j = 0; j < branch->label_list_length(); ++j) {
00598         AST_UnionLabel* label = branch->label(j);
00599         if (label->label_kind() == AST_UnionLabel::UL_default) {
00600           default_branch = branch;
00601         } else if (label->label_val()->ev()->u.bval) {
00602           true_branch = branch;
00603         } else if (!label->label_val()->ev()->u.bval) {
00604           false_branch = branch;
00605         }
00606       }
00607     }
00608 
00609     if (true_branch || false_branch) {
00610       be_global->impl_ <<
00611         "  if (" << switchExpr << ") {\n";
00612     } else {
00613       be_global->impl_ <<
00614         "  {\n";
00615     }
00616 
00617     if (true_branch || default_branch) {
00618       generateCaseBody(commonFn, true_branch ? true_branch : default_branch,
00619                        statementPrefix, namePrefix, uni, false, parens);
00620     }
00621 
00622     if (false_branch || (default_branch && true_branch)) {
00623       be_global->impl_ <<
00624         "  } else {\n";
00625       generateCaseBody(commonFn, false_branch ? false_branch : default_branch,
00626                        statementPrefix, namePrefix, uni, false, parens);
00627     }
00628 
00629     be_global->impl_ <<
00630       "  }\n";
00631 
00632     return !default_branch && bool(true_branch) != bool(false_branch);
00633 
00634   } else {
00635     be_global->impl_ <<
00636       "  switch (" << switchExpr << ") {\n";
00637     bool b(generateSwitchBody(commonFn, branches, discriminator,
00638                               statementPrefix, namePrefix, uni,
00639                               forceDisableDefault, parens, breaks));
00640     be_global->impl_ <<
00641       "  }\n";
00642     return b;
00643   }
00644 }
00645 
00646 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1