itl_generator.cpp

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 #include "itl_generator.h"
00009 #include "be_extern.h"
00010 #include "global_extern.h"
00011 
00012 #include "utl_identifier.h"
00013 #include "utl_labellist.h"
00014 
00015 #include <ast_fixed.h>
00016 
00017 using namespace AstTypeClassification;
00018 
00019 std::ostream&
00020 operator<<(std::ostream& out,
00021            const itl_generator::Indent& i)
00022 {
00023   out << std::string(static_cast<size_t> (i.generator->level_ * 2), ' ');
00024   return out;
00025 }
00026 
00027 std::ostream&
00028 operator<<(std::ostream& out,
00029            const itl_generator::Open& i)
00030 {
00031   i.generator->level_ += 1;
00032   return out;
00033 }
00034 
00035 std::ostream&
00036 operator<<(std::ostream& out,
00037            const itl_generator::Close& i)
00038 {
00039   i.generator->level_ -= 1;
00040   return out;
00041 }
00042 
00043 struct InlineType {
00044   AST_Type* type;
00045 
00046   explicit InlineType(AST_Type* t)
00047     : type(t)
00048   { }
00049 };
00050 
00051 std::ostream&
00052 operator<<(std::ostream& out,
00053            const InlineType& it)
00054 {
00055   AST_Typedef* td = AST_Typedef::narrow_from_decl(it.type);
00056   if (td) {
00057     be_global->itl_ << '"' << it.type->repoID() << '"';
00058     return out;
00059   }
00060 
00061   Classification c = classify(it.type);
00062   if (c & CL_STRING) {
00063     // TODO:  Support bounded strings.
00064     if (c & CL_WIDE) {
00065       be_global->itl_ << "{ \"kind\" : \"string\", \"note\" : { \"idl\" : { \"type\" : \"wstring\" } } }";
00066     }
00067     else {
00068       be_global->itl_ << "{ \"kind\" : \"string\" }";
00069     }
00070   }
00071   else if (c & CL_PRIMITIVE) {
00072     switch (AST_PredefinedType::narrow_from_decl(it.type)->pt()) {
00073     case AST_PredefinedType::PT_long:
00074       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 32 }";
00075       break;
00076     case AST_PredefinedType::PT_ulong:
00077       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 32, \"unsigned\" : true}";
00078       break;
00079     case AST_PredefinedType::PT_longlong:
00080       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 64 }";
00081       break;
00082     case AST_PredefinedType::PT_ulonglong:
00083       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 64, \"unsigned\" : true}";
00084       break;
00085     case AST_PredefinedType::PT_short:
00086       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 16 }";
00087       break;
00088     case AST_PredefinedType::PT_ushort:
00089       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 16, \"unsigned\" : true}";
00090       break;
00091     case AST_PredefinedType::PT_float:
00092       be_global->itl_ << "{ \"kind\" : \"float\", \"model\" : \"binary32\" }";
00093       break;
00094     case AST_PredefinedType::PT_double:
00095       be_global->itl_ << "{ \"kind\" : \"float\", \"model\" : \"binary64\" }";
00096       break;
00097     case AST_PredefinedType::PT_longdouble:
00098       be_global->itl_ << "{ \"kind\" : \"float\", \"model\" : \"binary128\" }";
00099       break;
00100     case AST_PredefinedType::PT_char:
00101       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 8, \"note\" : { \"presentation\" : { \"type\" : \"char\" } } }";
00102       break;
00103     case AST_PredefinedType::PT_wchar:
00104       be_global->itl_ << "{ \"kind\" : \"int\", \"note\" : { \"presentation\" : { \"type\" : \"char\" }, \"idl\" : { \"type\" : \"wchar\" } } }";
00105       break;
00106     case AST_PredefinedType::PT_boolean:
00107       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 1, \"note\" : { \"presentation\" : { \"type\" : \"bool\" } } }";
00108       break;
00109     case AST_PredefinedType::PT_octet:
00110       be_global->itl_ << "{ \"kind\" : \"int\", \"bits\" : 8, \"unsigned\" : true }";
00111       break;
00112     case AST_PredefinedType::PT_any:
00113     case AST_PredefinedType::PT_object:
00114     case AST_PredefinedType::PT_value:
00115     case AST_PredefinedType::PT_abstract:
00116     case AST_PredefinedType::PT_void:
00117     case AST_PredefinedType::PT_pseudo:
00118       // TODO
00119       break;
00120     }
00121   }
00122   else {
00123     be_global->itl_ << '"' << it.type->repoID() << '"';
00124   }
00125 
00126   return out;
00127 }
00128 
00129 void itl_generator::gen_prologue()
00130 {
00131   be_global->itl_ << Indent(this) << "{\n"
00132                   << Open(this)
00133                   << Indent(this) << "\"types\" :\n"
00134                   << Open(this)
00135                   << Indent(this) << "[\n";
00136 }
00137 
00138 void itl_generator::gen_epilogue()
00139 {
00140   be_global->itl_ << Indent(this) << "]\n"
00141                   << Close(this)
00142                   << Close(this)
00143                   << Indent(this) << "}\n";
00144 }
00145 
00146 void itl_generator::new_type()
00147 {
00148   if (count_ > 0)
00149     be_global->itl_ << Indent(this) << ",\n";
00150   ++count_;
00151 }
00152 
00153 bool itl_generator::gen_enum(AST_Enum*, UTL_ScopedName* /*name*/,
00154                              const std::vector<AST_EnumVal*>& contents, const char* repoid)
00155 {
00156   if (!be_global->generate_itl())
00157     return true;
00158 
00159   new_type();
00160 
00161   be_global->itl_ << Open(this)
00162                   << Indent(this) << "{\n"
00163                   << Open(this)
00164                   << Indent(this) << "\"kind\" : \"alias\",\n"
00165                   << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00166                   << Indent(this) << "\"type\" :\n"
00167                   << Open(this)
00168                   << Indent(this) << "{\n"
00169                   << Open(this)
00170                   << Indent(this) << "\"kind\" : \"int\",\n"
00171                   << Indent(this) << "\"bits\" : 32,\n"
00172                   << Indent(this) << "\"unsigned\" : true,\n"
00173                   << Indent(this) << "\"constrained\" : true,\n"
00174                   << Indent(this) << "\"values\" : {";
00175 
00176   for (size_t i = 0; i < contents.size(); ++i) {
00177     if (i > 0)
00178       be_global->itl_ << ", ";
00179     be_global->itl_ << '"' << contents[i]->local_name()->get_string() << '"'
00180                     << " : "
00181                     << '"' << i << '"';
00182   }
00183 
00184   be_global->itl_ << "}\n";
00185   be_global->itl_ << Close(this)
00186                   << Indent(this) << "}\n"
00187                   << Close(this);
00188 
00189   be_global->itl_ << Close(this)
00190                   << Indent(this) << "}\n"
00191                   << Close(this);
00192 
00193   return true;
00194 }
00195 
00196 bool itl_generator::gen_typedef(AST_Typedef*, UTL_ScopedName* /*name*/,
00197                                 AST_Type* base,
00198                                 const char* repoid)
00199 {
00200   if (!be_global->generate_itl())
00201     return true;
00202 
00203   new_type();
00204   switch (base->node_type()) {
00205   case AST_Decl::NT_sequence:
00206     {
00207       AST_Sequence *seq = AST_Sequence::narrow_from_decl(base);
00208       be_global->itl_ << Open(this)
00209                       << Indent(this) << "{\n"
00210                       << Open(this)
00211                       << Indent(this) << "\"kind\" : \"alias\",\n"
00212                       << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00213                       << Indent(this) << "\"type\" :\n"
00214                       << Open(this)
00215                       << Indent(this) << "{\n"
00216                       << Open(this)
00217                       << Indent(this) << "\"kind\" : \"sequence\",\n";
00218       if (!seq->unbounded()) {
00219         be_global->itl_ << Indent(this) << "\"capacity\" : " << seq->max_size()->ev()->u.ulval << ",\n";
00220       }
00221       be_global->itl_ << Indent(this) << "\"type\" : " << InlineType(seq->base_type()) << "\n"
00222                       << Close(this)
00223                       << Indent(this) << "}\n"
00224                       << Close(this)
00225                       << Close(this)
00226                       << Indent(this) << "}\n"
00227                       << Close(this);
00228       break;
00229     }
00230   case AST_Decl::NT_array:
00231     {
00232       AST_Array* arr = AST_Array::narrow_from_decl(base);
00233       be_global->itl_ << Open(this)
00234                       << Indent(this) << "{\n"
00235                       << Open(this)
00236                       << Indent(this) << "\"kind\" : \"alias\",\n"
00237                       << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00238                       << Indent(this) << "\"type\" :\n"
00239                       << Open(this)
00240                       << Indent(this) << "{\n"
00241                       << Open(this)
00242                       << Indent(this) << "\"kind\" : \"sequence\",\n"
00243                       << Indent(this) << "\"type\" : " << InlineType(arr->base_type()) << ",\n"
00244                       << Indent(this) << "\"size\" : [";
00245       ACE_CDR::ULong dims = arr->n_dims();
00246       for (size_t i = 0; i < dims; ++i) {
00247         if (i > 0)
00248           be_global->itl_ << ", ";
00249         be_global->itl_ << arr->dims()[i]->ev()->u.ulval;
00250       }
00251       be_global->itl_ << "]\n"
00252                       << Close(this)
00253                       << Indent(this) << "}\n"
00254                       << Close(this)
00255                       << Close(this)
00256                       << Indent(this) << "}\n"
00257                       << Close(this);
00258       break;
00259     }
00260   case AST_Decl::NT_fixed:
00261     {
00262       AST_Fixed* fixed = AST_Fixed::narrow_from_decl(base);
00263       unsigned digits = fixed->digits()->ev()->u.ulval;
00264       unsigned scale = fixed->scale()->ev()->u.ulval;
00265       be_global->itl_
00266         << Open(this) << Indent(this) << "{\n" << Open(this)
00267         << Indent(this) << "\"kind\" : \"alias\",\n"
00268         << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00269         << Indent(this) << "\"type\" : { "
00270           << "\"kind\" : \"fixed\", "
00271           << "\"digits\" : " << digits << ", "
00272           << "\"scale\" : " << scale << ", "
00273           << "\"base\" : 10 }\n"
00274         << Close(this) << Indent(this) << "}\n" << Close(this);
00275       break;
00276     }
00277   default:
00278     {
00279       be_global->itl_ << Open(this)
00280                       << Indent(this) << "{\n"
00281                       << Open(this)
00282                       << Indent(this) << "\"kind\" : \"alias\",\n"
00283                       << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00284                       << Indent(this) << "\"type\" : " << InlineType(base) << "\n"
00285                       << Close(this)
00286                       << Indent(this) << "}\n"
00287                       << Close(this);
00288 
00289       return true;
00290     }
00291   }
00292   return true;
00293 }
00294 
00295 bool itl_generator::gen_struct(AST_Structure*, UTL_ScopedName* name,
00296                                const std::vector<AST_Field*>& fields,
00297                                AST_Type::SIZE_TYPE, const char* repoid)
00298 {
00299   if (!be_global->generate_itl())
00300     return true;
00301 
00302   new_type();
00303   be_global->itl_ << Open(this)
00304                   << Indent(this) << "{\n"
00305                   << Open(this)
00306                   << Indent(this) << "\"kind\" : \"alias\",\n"
00307                   << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00308 
00309   // Check if this is defined as a primary data type
00310                   << Indent(this) << "\"note\" : { \"is_dcps_data_type\" : "
00311                   << (idl_global->is_dcps_type(name) ? "true" : "false")
00312                   << " },\n"
00313 
00314                   << Indent(this) << "\"type\" :\n"
00315                   << Open(this)
00316                   << Indent(this) << "{\n"
00317                   << Open(this)
00318                   << Indent(this) << "\"kind\" : \"record\",\n"
00319                   << Indent(this) << "\"fields\" :\n"
00320                   << Open(this)
00321                   << Indent(this) << "[\n";
00322 
00323   bool comma_flag = false;
00324   for (std::vector<AST_Field*>::const_iterator pos = fields.begin(), limit = fields.end();
00325        pos != limit;
00326        ++pos) {
00327     AST_Field* field = *pos;
00328     if (comma_flag) {
00329       be_global->itl_ << Indent(this) << ",\n";
00330     }
00331     be_global->itl_ << Open(this)
00332                     << Indent(this) << "{\n"
00333                     << Open(this)
00334                     << Indent(this) << "\"name\" : \"" << field->local_name()->get_string() << "\",\n"
00335                     << Indent(this) << "\"type\" : " << InlineType(field->field_type()) << "\n"
00336                     << Close(this)
00337                     << Indent(this) << "}\n"
00338                     << Close(this);
00339     comma_flag = true;
00340   }
00341 
00342   be_global->itl_ << Indent(this) << "]\n"
00343                   << Close(this)
00344                   << Close(this)
00345                   << Indent(this) << "}\n"
00346                   << Close(this)
00347                   << Close(this)
00348                   << Indent(this) << "}\n"
00349                   << Close(this);
00350 
00351 
00352   return true;
00353 }
00354 
00355 
00356 bool itl_generator::gen_union(AST_Union*, UTL_ScopedName* /*name*/,
00357                               const std::vector<AST_UnionBranch*>& cases,
00358                               AST_Type* _d,
00359                               const char* repoid)
00360 {
00361   if (!be_global->generate_itl())
00362     return true;
00363 
00364   new_type();
00365   be_global->itl_ << Open(this)
00366                   << Indent(this) << "{\n"
00367                   << Open(this)
00368                   << Indent(this) << "\"kind\" : \"alias\",\n"
00369                   << Indent(this) << "\"name\" : \"" << repoid << "\",\n"
00370                   << Indent(this) << "\"type\" :\n"
00371                   << Open(this)
00372                   << Indent(this) << "{\n"
00373                   << Open(this)
00374                   << Indent(this) << "\"kind\" : \"union\",\n"
00375                   << Indent(this) << "\"discriminator\" : " << InlineType(_d) << ",\n"
00376                   << Indent(this) << "\"fields\" :\n"
00377                   << Open(this)
00378                   << Indent(this) << "[\n";
00379 
00380   for (std::vector<AST_UnionBranch*>::const_iterator pos = cases.begin(), limit = cases.end();
00381        pos != limit;
00382        ++pos) {
00383     if (pos != cases.begin())
00384       be_global->itl_ << Indent(this) << ",\n";
00385 
00386     AST_UnionBranch *branch = *pos;
00387 
00388     be_global->itl_ << Open(this)
00389                     << Indent(this) << "{\n"
00390                     << Open(this)
00391                     << Indent(this) << "\"name\" : \"" << branch->local_name()->get_string() << "\",\n"
00392                     << Indent(this) << "\"type\" : " << InlineType(branch->field_type()) << ",\n"
00393 
00394                     << Indent(this) << "\"labels\" : [";
00395 
00396 
00397     unsigned long count = branch->label_list_length();
00398     for (unsigned long i = 0; i < count; i++)
00399       {
00400         if (i > 0)
00401           be_global->itl_ << ", ";
00402         AST_UnionLabel *label = branch->label(i);
00403         if (label->label_kind() == AST_UnionLabel::UL_default)
00404           {
00405             continue;
00406           }
00407         be_global->itl_ << "\"" << label->label_val()->n()->last_component()->get_string() << "\"";
00408       }
00409 
00410     be_global->itl_ << "]\n"
00411                     << Close(this)
00412                     << Indent(this) << "}\n"
00413                     << Close(this);
00414   }
00415 
00416   be_global->itl_ << Indent(this) << "]\n"
00417                   << Close(this)
00418                   << Close(this)
00419                   << Indent(this) << "}\n"
00420                   << Close(this)
00421                   << Close(this)
00422                   << Indent(this) << "}\n"
00423                   << Close(this);
00424 
00425   return true;
00426 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1