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

Generated on Fri Feb 12 20:05:23 2016 for OpenDDS by  doxygen 1.4.7