Synopsis - Cross-Reference

File: /Synopsis/Parsers/IDL/idldump.cc
  1// -*- c++ -*-
  2//                          Package   : omniidl
  3// idldump.cc               Created on: 1999/10/26
  4//			    Author    : Duncan Grisby (dpg1)
  5//
  6//    Copyright (C) 1999 AT&T Laboratories Cambridge
  7//
  8//  This file is part of omniidl.
  9//
 10//  omniidl is free software; you can redistribute it and/or modify it
 11//  under the terms of the GNU General Public License as published by
 12//  the Free Software Foundation; either version 2 of the License, or
 13//  (at your option) any later version.
 14//
 15//  This program is distributed in the hope that it will be useful,
 16//  but WITHOUT ANY WARRANTY; without even the implied warranty of
 17//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 18//  General Public License for more details.
 19//
 20//  You should have received a copy of the GNU General Public License
 21//  along with this program; if not, write to the Free Software
 22//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 23//  02111-1307, USA.
 24//
 25// Description:
 26//   
 27//   Visitor object to dump the tree
 28
 29// $Id: idldump.cc,v 1.16.2.3 2005/06/08 09:40:38 dgrisby Exp $
 30// $Log: idldump.cc,v $
 31// Revision 1.16.2.3  2005/06/08 09:40:38  dgrisby
 32// Update example code, IDL dumping.
 33//
 34// Revision 1.16.2.2  2003/09/04 14:00:28  dgrisby
 35// ValueType IDL updates.
 36//
 37// Revision 1.16.2.1  2003/03/23 21:01:46  dgrisby
 38// Start of omniORB 4.1.x development branch.
 39//
 40// Revision 1.11.2.10  2002/02/25 15:02:18  dpg1
 41// Dump wstring constants properly.
 42//
 43// Revision 1.11.2.9  2002/02/18 11:59:22  dpg1
 44// Full autoconf support.
 45//
 46// Revision 1.11.2.8  2001/11/14 17:13:43  dpg1
 47// Long double support.
 48//
 49// Revision 1.11.2.7  2001/08/29 11:54:20  dpg1
 50// Clean up const handling in IDL compiler.
 51//
 52// Revision 1.11.2.6  2001/06/12 11:35:25  dpg1
 53// Minor omniidl tweaks for valuetype.
 54//
 55// Revision 1.11.2.5  2001/03/13 10:32:11  dpg1
 56// Fixed point support.
 57//
 58// Revision 1.11.2.4  2000/11/01 15:57:03  dpg1
 59// More updates for 2.4.
 60//
 61// Revision 1.11.2.3  2000/11/01 12:45:56  dpg1
 62// Update to CORBA 2.4 specification.
 63//
 64// Revision 1.11.2.2  2000/10/10 10:18:50  dpg1
 65// Update omniidl front-end from omni3_develop.
 66//
 67// Revision 1.9.2.2  2000/08/29 10:20:26  dpg1
 68// Operations and attributes now have repository ids.
 69//
 70// Revision 1.9.2.1  2000/08/14 14:35:13  dpg1
 71// IDL dumping now properly escapes string and char constants
 72//
 73// Revision 1.9  2000/02/03 14:50:08  dpg1
 74// Native declarations can now be used as types.
 75//
 76// Revision 1.8  1999/11/17 18:07:23  dpg1
 77// Tiny change to enum printing.
 78//
 79// Revision 1.7  1999/11/17 18:05:16  dpg1
 80// Tiny change to enum printing.
 81//
 82// Revision 1.6  1999/11/17 17:50:42  dpg1
 83// Unions with nested declarations now output properly.
 84//
 85// Revision 1.5  1999/11/02 17:07:27  dpg1
 86// Changes to compile on Solaris.
 87//
 88// Revision 1.4  1999/11/01 20:19:56  dpg1
 89// Support for union switch types declared inside the switch statement.
 90//
 91// Revision 1.3  1999/10/29 15:43:15  dpg1
 92// Code to detect recursive structs and unions.
 93//
 94// Revision 1.2  1999/10/29 10:01:12  dpg1
 95// Small fixes.
 96//
 97// Revision 1.1  1999/10/27 14:05:58  dpg1
 98// *** empty log message ***
 99//
100
101#include <idldump.h>
102#include <idlutil.h>
103#include <idlast.h>
104#include <idltype.h>
105
106#include <stdio.h>
107#include <ctype.h>
108
109DumpVisitor::
110DumpVisitor()
111  : indent_(0)
112{
113}
114
115DumpVisitor::
116~DumpVisitor()
117{
118}
119
120void
121DumpVisitor::
122printIndent()
123{
124  for (int i=0; i<indent_; ++i)
125    printf("  ");
126}
127
128void
129DumpVisitor::
130printScopedName(const ScopedName* sn)
131{
132  char* ssn = sn->toString();
133  printf("%s", ssn);
134  delete [] ssn;
135}
136
137void
138DumpVisitor::
139printString(const char* str)
140{
141  const char* c;
142  for (c=str; *c; c++) {
143    if (*c == '\\')
144      printf("\\\\");
145    else if (isprint(*c))
146      putchar(*c);
147    else
148      printf("\\%03o", (int)(unsigned char)*c);
149  }
150}
151
152void
153DumpVisitor::
154printChar(const char c)
155{
156  if (c == '\\')
157    printf("\\\\");
158  else if (isprint(c))
159    putchar(c);
160  else
161    printf("\\%03o", (int)(unsigned char)c);
162}
163
164
165void
166DumpVisitor::
167visitAST(AST* a)
168{
169  printf("\n");
170  for (Decl* d = a->declarations(); d; d = d->next()) {
171    d->accept(*this);
172    printf(";\n\n");
173  }
174}
175
176void
177DumpVisitor::
178visitModule(Module* m)
179{
180  printf("module %s { // RepoId = %s, file = %s, line = %d, %s\n",
181	 m->identifier(), m->repoId(), m->file(), m->line(),
182	 m->mainFile() ? "in main file" : "not in main file");
183  ++indent_;
184  for (Decl* d = m->definitions(); d; d = d->next()) {
185    printIndent();
186    d->accept(*this);
187    printf(";\n");
188  }
189  --indent_;
190  printIndent();
191  printf("}");
192}
193
194void
195DumpVisitor::
196visitInterface(Interface* i)
197{
198  if (i->abstract()) printf("abstract ");
199  if (i->local())    printf("local ");
200  printf("interface %s ", i->identifier());
201
202  if (i->inherits()) {
203    printf(": ");
204    char* ssn;
205    for (InheritSpec* is = i->inherits(); is; is = is->next()) {
206      ssn = is->interface()->scopedName()->toString();
207      printf("%s%s ", ssn, is->next() ? "," : "");
208      delete [] ssn;
209    }
210  }
211  printf("{ // RepoId = %s\n", i->repoId());
212
213  ++indent_;
214  for (Decl* d = i->contents(); d; d = d->next()) {
215    printIndent();
216    d->accept(*this);
217    printf(";\n");
218  }
219  --indent_;
220  printIndent();
221  printf("}");
222}
223
224void
225DumpVisitor::
226visitForward(Forward* f)
227{
228  if (f->abstract()) printf("abstract ");
229  if (f->local())    printf("local ");
230  printf("interface %s; // RepoId = %s", f->identifier(), f->repoId());
231}
232
233static void
234printdouble(IDL_Double d)
235{
236  // .17g guarantees an IEEE 754 double can be exactly reconstructed,
237  // but it prints integers without a trailing .0, so we must put it
238  // back on in that case.
239  char buffer[1024];
240  sprintf(buffer, "%.17g", d);
241  char* c = buffer;
242  if (*c == '-') ++c;
243  for (; *c; c++) {
244    if (!isdigit(*c))
245      break;
246  }
247  if (*c == '\0') {
248    *c++ = '.';
249    *c++ = '0';
250    *c++ = '\0';
251  }
252  printf("%s", buffer);
253}
254
255#ifdef HAS_LongDouble
256static void
257printlongdouble(IDL_LongDouble d)
258{
259  // Can't find a reference for how many digits it enough for long
260  // double. 40 is probably enough.
261  char buffer[1024];
262  sprintf(buffer, "%.40Lg", d);
263  char* c = buffer;
264  if (*c == '-') ++c;
265  for (; *c; c++) {
266    if (!isdigit(*c))
267      break;
268  }
269  if (*c == '\0') {
270    *c++ = '.';
271    *c++ = '0';
272    *c++ = '\0';
273  }
274  printf("%s", buffer);
275}
276#endif
277
278
279static void
280printwchar(IDL_WChar wc)
281{
282  if (wc == '\\')
283    printf("L'\\\\'");
284  else if (wc < 0xff && isprint(wc))
285    printf("L'%c'", (char)wc);
286  else
287    printf("L'\\u%04x", (int)wc);
288}
289
290static void
291printwstring(const IDL_WChar* ws)
292{
293  printf("L\"");
294  int i, wc;
295  for (i=0; ws[i]; ++i) {
296    wc = ws[i];
297    if (wc == '\\')
298      printf("\\\\");
299    else if (wc < 0xff && isprint(wc))
300      putchar(wc);
301    else
302      printf("\\u%04x", (int)wc);
303  }
304  putchar('"');
305}
306
307
308void
309DumpVisitor::
310visitConst(Const* c)
311{
312  printf("const ");
313
314  c->constType()->accept(*this);
315  printf(" %s = ", c->identifier());
316
317  switch(c->constKind()) {
318  case IdlType::tk_short:   printf("%hd", c->constAsShort());           break;
319  case IdlType::tk_long:    printf("%ld", (long)c->constAsLong());      break;
320  case IdlType::tk_ushort:  printf("%hu", c->constAsUShort());          break;
321  case IdlType::tk_ulong:   printf("%lu", (unsigned long)c->constAsULong());
322                                                                        break;
323  case IdlType::tk_float:   printdouble(c->constAsFloat());             break;
324  case IdlType::tk_double:  printdouble(c->constAsDouble());            break;
325  case IdlType::tk_boolean:
326    printf("%s", c->constAsBoolean() ? "TRUE" : "FALSE");
327    break;
328  case IdlType::tk_char:
329    printf("'");
330    printChar(c->constAsChar());
331    printf("'");
332    break;
333  case IdlType::tk_octet:   printf("%d",     (int)c->constAsOctet());  break;
334  case IdlType::tk_string:
335    printf("\"");
336    printString(c->constAsString());
337    printf("\"");
338    break;
339#ifdef HAS_LongLong
340  case IdlType::tk_longlong:  printf("%Ld", c->constAsLongLong());     break;
341  case IdlType::tk_ulonglong: printf("%Lu", c->constAsULongLong());    break;
342#endif
343#ifdef HAS_LongDouble
344  case IdlType::tk_longdouble:printlongdouble(c->constAsLongDouble()); break;
345#endif
346  case IdlType::tk_wchar:     printwchar(c->constAsWChar());           break;
347  case IdlType::tk_wstring:   printwstring(c->constAsWString());       break;
348
349  case IdlType::tk_fixed:
350    {
351      char* fs = c->constAsFixed()->asString();
352      printf("%sd", fs);
353      delete [] fs;
354    }
355    break;
356
357  case IdlType::tk_enum:      c->constAsEnumerator()->accept(*this);   break;
358  default:
359    assert(0);
360  }
361}
362
363void
364DumpVisitor::
365visitDeclarator(Declarator* d)
366{
367  printf("%s", d->identifier());
368  for (ArraySize* s = d->sizes(); s; s = s->next())
369    printf("[%d]", s->size());
370}
371
372void
373DumpVisitor::
374visitTypedef(Typedef* t)
375{
376  printf("typedef ");
377
378  if (t->constrType()) { 
379    assert(t->aliasType()->kind() == IdlType::tk_struct ||
380	   t->aliasType()->kind() == IdlType::tk_union  ||
381	   t->aliasType()->kind() == IdlType::tk_enum);
382
383    ((DeclaredType*)t->aliasType())->decl()->accept(*this);
384  }
385  else
386    t->aliasType()->accept(*this);
387
388  printf(" ");
389  for (Declarator* d = t->declarators(); d; d = (Declarator*)d->next()) {
390    d->accept(*this);
391    if (d->next()) printf(", ");
392  }
393}
394
395void
396DumpVisitor::
397visitMember(Member* m)
398{
399  if (m->constrType()) {
400    assert(m->memberType()->kind() == IdlType::tk_struct ||
401	   m->memberType()->kind() == IdlType::tk_union  ||
402	   m->memberType()->kind() == IdlType::tk_enum);
403
404    ((DeclaredType*)m->memberType())->decl()->accept(*this);
405  }
406  else
407    m->memberType()->accept(*this);
408
409  printf(" ");
410  for (Declarator* d = m->declarators(); d; d = (Declarator*)d->next()) {
411    d->accept(*this);
412    if (d->next())
413      printf(", ");
414  }
415}
416
417void
418DumpVisitor::
419visitStruct(Struct* s)
420{
421  printf("struct %s { // RepoId = %s%s\n", s->identifier(), s->repoId(),
422	 s->recursive() ? " recursive" : "");
423
424  ++indent_;
425  for (Member* m = s->members(); m; m = (Member*)m->next()) {
426    printIndent();
427    m->accept(*this);
428    printf(";\n");
429  }
430  --indent_;
431  printIndent();
432  printf("}");
433}
434
435void
436DumpVisitor::
437visitStructForward(StructForward* s)
438{
439  printf("struct %s", s->identifier());
440}
441
442
443void
444DumpVisitor::
445visitException(Exception* e)
446{
447  printf("exception %s {\n", e->identifier());
448
449  ++indent_;
450  for (Member* m = e->members(); m; m = (Member*)m->next()) {
451    printIndent();
452    m->accept(*this);
453    printf(";\n");
454  }
455  --indent_;
456  printIndent();
457  printf("}");
458}
459
460void
461DumpVisitor::
462visitCaseLabel(CaseLabel* l)
463{
464  if (l->isDefault())
465    printf("default /* ");
466  else
467    printf("case ");
468
469  switch(l->labelKind()) {
470  case IdlType::tk_short:  printf("%hd", l->labelAsShort());        break;
471  case IdlType::tk_long:   printf("%ld", (long)l->labelAsLong());   break;
472  case IdlType::tk_ushort: printf("%hu", l->labelAsUShort());       break;
473  case IdlType::tk_ulong:  printf("%lu", (unsigned long)l->labelAsULong());
474                                                                    break;
475  case IdlType::tk_boolean:
476    printf("%s", l->labelAsBoolean() ? "TRUE" : "FALSE");
477    break;
478  case IdlType::tk_char:
479    printf("'");
480    printChar(l->labelAsChar());
481    printf("'");
482    break;
483#ifdef HAS_LongLong
484  case IdlType::tk_longlong:  printf("%Ld", l->labelAsLongLong());  break;
485  case IdlType::tk_ulonglong: printf("%Lu", l->labelAsULongLong()); break;
486#endif
487  case IdlType::tk_wchar:     printf("'\\u%hx", l->labelAsWChar()); break;
488  case IdlType::tk_enum: l->labelAsEnumerator()->accept(*this);     break;
489  default:
490    assert(0);
491  }
492  if (l->isDefault())
493    printf(" */:");
494  else
495    printf(":");
496}
497
498void
499DumpVisitor::
500visitUnionCase(UnionCase* c)
501{
502  for (CaseLabel* l = c->labels(); l; l = (CaseLabel*)l->next()) {
503    l->accept(*this);
504    if (l->next()) printf(" ");
505  }
506  printf("\n");
507  ++indent_;
508  printIndent();
509
510  if (c->constrType()) {
511    assert(c->caseType()->kind() == IdlType::tk_struct ||
512	   c->caseType()->kind() == IdlType::tk_union  ||
513	   c->caseType()->kind() == IdlType::tk_enum);
514
515    ((DeclaredType*)c->caseType())->decl()->accept(*this);
516  }
517  else
518    c->caseType()->accept(*this);
519
520  printf(" %s", c->declarator()->identifier());
521  --indent_;
522}
523
524void
525DumpVisitor::
526visitUnion(Union* u)
527{
528  printf("union %s switch (", u->identifier());
529
530  if (u->constrType())
531    ((DeclaredType*)u->switchType())->decl()->accept(*this);
532  else
533    u->switchType()->accept(*this);
534  printf(") { // RepoId = %s%s\n", u->repoId(),
535	 u->recursive() ? " recursive" : "");
536  ++indent_;
537  for (UnionCase* c = u->cases(); c; c = (UnionCase*)c->next()) {
538    printIndent();
539    c->accept(*this);
540    printf(";\n");
541  }
542  --indent_;
543  printIndent();
544  printf("}");
545}
546
547void
548DumpVisitor::
549visitUnionForward(UnionForward* u)
550{
551  printf("union %s", u->identifier());
552}
553
554void
555DumpVisitor::
556visitEnumerator(Enumerator* e)
557{
558  char* ssn = e->scopedName()->toString();
559  printf("%s", ssn);
560  delete [] ssn;
561}
562
563void
564DumpVisitor::
565visitEnum(Enum* e)
566{
567  printf("enum %s { // RepoId = %s\n", e->identifier(), e->repoId());
568  ++indent_;
569  for (Enumerator* n = e->enumerators(); n; n = (Enumerator*)n->next()) {
570    printIndent();
571    printf("%s%s\n", n->identifier(), n->next() ? "," : "");
572  }
573  --indent_;
574  printIndent();
575  printf("}");
576}
577
578void
579DumpVisitor::
580visitAttribute(Attribute* a)
581{
582  if (a->readonly()) printf("readonly ");
583  printf("attribute ");
584  a->attrType()->accept(*this);
585  printf(" ");
586  for (Declarator* d = a->declarators(); d; d = (Declarator*)d->next()) {
587    d->accept(*this);
588    if (d->next()) printf(", ");
589  }
590}
591
592void
593DumpVisitor::
594visitParameter(Parameter* p)
595{
596  switch (p->direction()) {
597  case 0: printf("in ");    break;
598  case 1: printf("out ");   break;
599  case 2: printf("inout "); break;
600  }
601  p->paramType()->accept(*this);
602  printf(" %s", p->identifier());
603}
604
605void
606DumpVisitor::
607visitOperation(Operation* o)
608{
609  if (o->oneway()) printf("oneway ");
610  o->returnType()->accept(*this);
611  printf(" %s(", o->identifier());
612
613  for (Parameter* p = o->parameters(); p; p = (Parameter*)p->next()) {
614    p->accept(*this);
615    if (p->next()) printf(", ");
616  }
617  printf(")");
618
619  if (o->raises()) {
620    printf(" raises (");
621    char* ssn;
622    for (RaisesSpec* r = o->raises(); r; r = r->next()) {
623      ssn = r->exception()->scopedName()->toString();
624      printf("%s", ssn);
625      delete [] ssn;
626      if (r->next()) printf(", ");
627    }
628    printf(")");
629  }
630  if (o->contexts()) {
631    printf(" context (");
632    for (ContextSpec* c = o->contexts(); c; c = c->next()) {
633      printf("\"%s\"", c->context());
634      if (c->next()) printf(", ");
635    }
636    printf(")");
637  }
638}
639
640void
641DumpVisitor::
642visitNative(Native* n)
643{
644  printf("native %s", n->identifier());
645}
646
647void
648DumpVisitor::
649visitStateMember(StateMember* s)
650{
651  switch(s->memberAccess()) {
652  case 0: printf("public ");  break;
653  case 1: printf("private "); break;
654  }
655
656  if (s->constrType()) { 
657    assert(s->memberType()->kind() == IdlType::tk_struct ||
658	   s->memberType()->kind() == IdlType::tk_union  ||
659	   s->memberType()->kind() == IdlType::tk_enum);
660
661    ((DeclaredType*)s->memberType())->decl()->accept(*this);
662  }
663  else
664    s->memberType()->accept(*this);
665
666  printf(" ");
667
668  for (Declarator* d = s->declarators(); d; d = (Declarator*)d->next()) {
669    d->accept(*this);
670    if (d->next()) printf(", ");
671  }
672}
673
674void
675DumpVisitor::
676visitFactory(Factory* f)
677{
678  printf("factory %s(", f->identifier());
679  for (Parameter* p = f->parameters(); p; p = (Parameter*)p->next()) {
680    p->accept(*this);
681    if (p->next()) printf(", ");
682  }
683  printf(")");
684  if (f->raises()) {
685    printf(" raises (");
686    char* ssn;
687    for (RaisesSpec* r = f->raises(); r; r = r->next()) {
688      ssn = r->exception()->scopedName()->toString();
689      printf("%s", ssn);
690      delete [] ssn;
691      if (r->next()) printf(", ");
692    }
693    printf(")");
694  }
695}
696
697void
698DumpVisitor::
699visitValueForward(ValueForward* f)
700{
701  if (f->abstract()) printf("abstract ");
702  printf("valuetype %s", f->identifier());
703}
704
705void
706DumpVisitor::
707visitValueBox(ValueBox* b)
708{
709  printf("valuetype %s ", b->identifier());
710
711  if (b->constrType()) { 
712    assert(b->boxedType()->kind() == IdlType::tk_struct ||
713	   b->boxedType()->kind() == IdlType::tk_union  ||
714	   b->boxedType()->kind() == IdlType::tk_enum);
715
716    ((DeclaredType*)b->boxedType())->decl()->accept(*this);
717  }
718  else
719    b->boxedType()->accept(*this);
720}
721
722void
723DumpVisitor::
724visitValueAbs(ValueAbs* v)
725{
726  printf("abstract valuetype %s ", v->identifier());
727
728  if (v->inherits()) {
729    printf(": ");
730    char* ssn;
731    for (ValueInheritSpec* vis = v->inherits(); vis; vis = vis->next()) {
732      ssn = vis->value()->scopedName()->toString();
733      printf("%s%s%s ",
734	     vis->truncatable() ? "truncatable " : "",
735	     ssn, vis->next() ? "," : "");
736      delete [] ssn;
737    }
738  }
739  if (v->supports()) {
740    printf("supports ");
741    char* ssn;
742    for (InheritSpec* is = v->supports(); is; is = is->next()) {
743      ssn = is->interface()->scopedName()->toString();
744      printf("%s%s ", ssn, is->next() ? "," : "");
745      delete [] ssn;
746    }
747  }
748  printf("{\n");
749
750  ++indent_;
751  for (Decl* d = v->contents(); d; d = d->next()) {
752    printIndent();
753    d->accept(*this);
754    printf(";\n");
755  }
756  --indent_;
757  printIndent();
758  printf("}");
759}
760
761void
762DumpVisitor::
763visitValue(Value* v)
764{
765  if (v->custom()) printf("custom ");
766  printf("valuetype %s ", v->identifier());
767
768  if (v->inherits()) {
769    printf(": ");
770    char* ssn;
771    for (ValueInheritSpec* vis = v->inherits(); vis; vis = vis->next()) {
772      ssn = vis->value()->scopedName()->toString();
773      printf("%s%s%s ",
774	     vis->truncatable() ? "truncatable " : "",
775	     ssn, vis->next() ? "," : "");
776      delete [] ssn;
777    }
778  }
779  if (v->supports()) {
780    printf("supports ");
781    char* ssn;
782    for (InheritSpec* is = v->supports(); is; is = is->next()) {
783      ssn = is->interface()->scopedName()->toString();
784      printf("%s%s ", ssn, is->next() ? "," : "");
785      delete [] ssn;
786    }
787  }
788  printf("{\n");
789
790  ++indent_;
791  for (Decl* d = v->contents(); d; d = d->next()) {
792    printIndent();
793    d->accept(*this);
794    printf(";\n");
795  }
796  --indent_;
797  printIndent();
798  printf("}");
799}
800
801
802// Types
803
804void
805DumpVisitor::
806visitBaseType(BaseType* t)
807{
808  printf("%s", t->kindAsString());
809}
810
811void
812DumpVisitor::
813visitStringType(StringType* t)
814{
815  if (t->bound())
816    printf("string<%ld>", (long)t->bound());
817  else
818    printf("string");
819}
820
821void
822DumpVisitor::
823visitWStringType(WStringType* t)
824{
825  if (t->bound())
826    printf("wstring<%ld>", (long)t->bound());
827  else
828    printf("wstring");
829}
830
831void
832DumpVisitor::
833visitSequenceType(SequenceType* t)
834{
835  printf("sequence<");
836  t->seqType()->accept(*this);
837
838  if (t->bound())
839    printf(", %ld>", (long)t->bound());
840  else
841    printf(">");
842}
843
844void
845DumpVisitor::
846visitFixedType(FixedType* t)
847{
848  if (t->digits() > 0)
849    printf("fixed<%hu,%hd>", t->digits(), t->scale());
850  else
851    printf("fixed");
852}
853
854#define DTCASE(tk, dt, dk) \
855  case IdlType::tk: \
856    { \
857      dt* d = (dt*)t->decl(); \
858      assert(d->kind() == Decl::dk); \
859      printScopedName(d->scopedName()); \
860      break; \
861    }
862
863void
864DumpVisitor::
865visitDeclaredType(DeclaredType* t)
866{
867  switch(t->kind()) {
868  case IdlType::tk_objref:
869  case IdlType::tk_abstract_interface:
870  case IdlType::tk_local_interface:
871    {
872      if (t->decl()) {
873	if (t->decl()->kind() == Decl::D_INTERFACE) {
874	  Interface* i = (Interface*)t->decl();
875	  printScopedName(i->scopedName());
876	}
877	else {
878	  assert(t->decl()->kind() == Decl::D_FORWARD);
879	  Forward* f = (Forward*)t->decl();
880	  printScopedName(f->scopedName());
881	}
882      }
883      else
884	printf("Object");
885      break;
886    }
887  case IdlType::tk_value:
888    {
889      if (t->decl()) {
890	if (t->decl()->kind() == Decl::D_VALUE) {
891	  Value* v = (Value*)t->decl();
892	  printScopedName(v->scopedName());
893	}
894	else {
895	  assert(t->decl()->kind() == Decl::D_VALUEFORWARD);
896	  ValueForward* f = (ValueForward*)t->decl();
897	  printScopedName(f->scopedName());
898	}
899      }
900      else
901	printf("Object");
902      break;
903    }
904  DTCASE(tk_struct,        Struct,            D_STRUCT)
905  DTCASE(ot_structforward, StructForward,     D_STRUCTFORWARD)
906  DTCASE(tk_union,  	   Union,      	      D_UNION)
907  DTCASE(ot_unionforward,  UnionForward,      D_UNIONFORWARD)
908  DTCASE(tk_enum,   	   Enum,       	      D_ENUM)
909  DTCASE(tk_alias,  	   Declarator, 	      D_DECLARATOR)
910  DTCASE(tk_native, 	   Native,     	      D_NATIVE)
911  DTCASE(tk_value_box,     ValueBox,          D_VALUEBOX)
912  default:
913    printf("%s", t->kindAsString());
914  }
915}