Changeset c8ffe20b


Ignore:
Timestamp:
Nov 15, 2014, 10:46:42 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, resolv-new, string, with_gc
Children:
1ead581
Parents:
8c17ab0
Message:

reformat files

Location:
translator
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • translator/Parser/TypeData.cc

    r8c17ab0 rc8ffe20b  
    1010
    1111
    12 TypeData::TypeData( Kind k )
    13   : kind( k ), base( 0 ), forall( 0 )
    14 {
    15   switch( kind ) {
    16   case Unknown:
    17   case Pointer:
    18   case EnumConstant:
    19     // nothing else to initialize
    20     break;
    21 
    22   case Basic:
    23     basic = new Basic_t;
    24     break;
    25 
    26   case Array:
    27     array = new Array_t;
    28     array->dimension = 0;
    29     array->isVarLen = false;
    30     array->isStatic = false;
    31     break;
    32 
    33   case Function:
    34     function = new Function_t;
    35     function->params = 0;
    36     function->idList = 0;
    37     function->oldDeclList = 0;
    38     function->body = 0;
    39     function->hasBody = false;
    40     break;
    41 
    42   case Aggregate:
    43     aggregate = new Aggregate_t;
    44     aggregate->params = 0;
    45     aggregate->actuals = 0;
    46     aggregate->members = 0;
    47     break;
    48 
    49   case AggregateInst:
    50     aggInst = new AggInst_t;
    51     aggInst->aggregate = 0;
    52     aggInst->params = 0;
    53     break;
    54 
    55   case Enum:
    56     enumeration = new Enumeration_t;
    57     enumeration->constants = 0;
    58     break;
    59 
    60   case Symbolic:
    61   case SymbolicInst:
    62     symbolic = new Symbolic_t;
    63     symbolic->params = 0;
    64     symbolic->actuals = 0;
    65     symbolic->assertions = 0;
    66     break;
    67 
    68   case Variable:
    69     variable = new Variable_t;
    70     variable->tyClass = DeclarationNode::Type;
    71     variable->assertions = 0;
    72     break;
    73 
    74   case Tuple:
    75     tuple = new Tuple_t;
    76     tuple->members = 0;
    77     break;
     12TypeData::TypeData( Kind k ) : kind( k ), base( 0 ), forall( 0 ) {
     13    switch ( kind ) {
     14      case Unknown:
     15      case Pointer:
     16      case EnumConstant:
     17        // nothing else to initialize
     18        break;
     19      case Basic:
     20        basic = new Basic_t;
     21        break;
     22      case Array:
     23        array = new Array_t;
     24        array->dimension = 0;
     25        array->isVarLen = false;
     26        array->isStatic = false;
     27        break;
     28      case Function:
     29        function = new Function_t;
     30        function->params = 0;
     31        function->idList = 0;
     32        function->oldDeclList = 0;
     33        function->body = 0;
     34        function->hasBody = false;
     35        break;
     36      case Aggregate:
     37        aggregate = new Aggregate_t;
     38        aggregate->params = 0;
     39        aggregate->actuals = 0;
     40        aggregate->members = 0;
     41        break;
     42      case AggregateInst:
     43        aggInst = new AggInst_t;
     44        aggInst->aggregate = 0;
     45        aggInst->params = 0;
     46        break;
     47      case Enum:
     48        enumeration = new Enumeration_t;
     49        enumeration->constants = 0;
     50        break;
     51      case Symbolic:
     52      case SymbolicInst:
     53        symbolic = new Symbolic_t;
     54        symbolic->params = 0;
     55        symbolic->actuals = 0;
     56        symbolic->assertions = 0;
     57        break;
     58      case Variable:
     59        variable = new Variable_t;
     60        variable->tyClass = DeclarationNode::Type;
     61        variable->assertions = 0;
     62        break;
     63      case Tuple:
     64        tuple = new Tuple_t;
     65        tuple->members = 0;
     66        break;
    7867 
    79   case Typeof:
    80     typeexpr = new Typeof_t;
    81     typeexpr->expr = 0;
    82     break;
     68      case Typeof:
     69        typeexpr = new Typeof_t;
     70        typeexpr->expr = 0;
     71        break;
    8372 
    84   case Attr:
    85     attr = new Attr_t;
    86     attr->expr = 0;
    87     attr->type = 0;
    88     break;
    89   }
    90 }
    91 
    92 TypeData::~TypeData()
    93 {
    94   delete base;
    95   delete forall;
    96 
    97   switch( kind ) {
    98   case Unknown:
    99   case Pointer:
    100   case EnumConstant:
    101     // nothing to destroy
    102     break;
    103 
    104   case Basic:
    105     delete basic;
    106     break;
    107 
    108   case Array:
    109     delete array->dimension;
    110     delete array;
    111     break;
    112 
    113   case Function:
    114     delete function->params;
    115     delete function->idList;
    116     delete function->oldDeclList;
    117     delete function->body;
    118     delete function;
    119     break;
    120 
    121   case Aggregate:
    122     delete aggregate->params;
    123     delete aggregate->actuals;
    124     delete aggregate->members;
    125     delete aggregate;
    126     break;
    127 
    128   case AggregateInst:
    129     delete aggInst->aggregate;
    130     delete aggInst->params;
    131     delete aggInst;
    132     break;
    133 
    134   case Enum:
    135     delete enumeration->constants;
    136     delete enumeration;
    137     break;
    138 
    139   case Symbolic:
    140   case SymbolicInst:
    141     delete symbolic->params;
    142     delete symbolic->actuals;
    143     delete symbolic->assertions;
    144     delete symbolic;
    145     break;
    146 
    147   case Variable:
    148     delete variable->assertions;
    149     delete variable;
    150     break;
    151 
    152   case Tuple:
    153     delete tuple->members;
    154     delete tuple;
    155     break;
     73      case Attr:
     74        attr = new Attr_t;
     75        attr->expr = 0;
     76        attr->type = 0;
     77        break;
     78    }
     79}
     80
     81TypeData::~TypeData() {
     82    delete base;
     83    delete forall;
     84
     85    switch ( kind ) {
     86      case Unknown:
     87      case Pointer:
     88      case EnumConstant:
     89        // nothing to destroy
     90        break;
     91      case Basic:
     92        delete basic;
     93        break;
     94      case Array:
     95        delete array->dimension;
     96        delete array;
     97        break;
     98      case Function:
     99        delete function->params;
     100        delete function->idList;
     101        delete function->oldDeclList;
     102        delete function->body;
     103        delete function;
     104        break;
     105      case Aggregate:
     106        delete aggregate->params;
     107        delete aggregate->actuals;
     108        delete aggregate->members;
     109        delete aggregate;
     110        break;
     111      case AggregateInst:
     112        delete aggInst->aggregate;
     113        delete aggInst->params;
     114        delete aggInst;
     115        break;
     116      case Enum:
     117        delete enumeration->constants;
     118        delete enumeration;
     119        break;
     120      case Symbolic:
     121      case SymbolicInst:
     122        delete symbolic->params;
     123        delete symbolic->actuals;
     124        delete symbolic->assertions;
     125        delete symbolic;
     126        break;
     127      case Variable:
     128        delete variable->assertions;
     129        delete variable;
     130        break;
     131      case Tuple:
     132        delete tuple->members;
     133        delete tuple;
     134        break;
    156135 
    157   case Typeof:
    158     delete typeexpr->expr;
    159     delete typeexpr;
    160     break;
     136      case Typeof:
     137        delete typeexpr->expr;
     138        delete typeexpr;
     139        break;
    161140 
    162   case Attr:
    163     delete attr->expr;
    164     delete attr->type;
    165     delete attr;
    166     break;
    167   }
    168 }
    169 
    170 TypeData *
    171 TypeData::clone() const
    172 {
    173   TypeData *newtype = new TypeData( kind );
    174   newtype->qualifiers = qualifiers;
    175   newtype->base = maybeClone( base );
    176   newtype->forall = maybeClone( forall );
    177 
    178   switch( kind ) {
    179   case Unknown:
    180   case EnumConstant:
    181   case Pointer:
    182     // nothing else to copy
    183     break;
    184 
    185   case Basic:
    186     newtype->basic->typeSpec = basic->typeSpec;
    187     newtype->basic->modifiers = basic->modifiers;
    188     break;
    189 
    190   case Array:
    191     newtype->array->dimension = maybeClone( array->dimension );
    192     newtype->array->isVarLen = array->isVarLen;
    193     newtype->array->isStatic = array->isStatic;
    194     break;
    195 
    196   case Function:
    197     newtype->function->params = maybeClone( function->params );
    198     newtype->function->idList = maybeClone( function->idList );
    199     newtype->function->oldDeclList = maybeClone( function->oldDeclList );
    200     newtype->function->body = maybeClone( function->body );
    201     newtype->function->hasBody = function->hasBody;
    202     newtype->function->newStyle = function->newStyle;
    203     break;
    204 
    205   case Aggregate:
    206     newtype->aggregate->params = maybeClone( aggregate->params );
    207     newtype->aggregate->actuals = maybeClone( aggregate->actuals );
    208     newtype->aggregate->members = maybeClone( aggregate->members );
    209     newtype->aggregate->name = aggregate->name;
    210     newtype->aggregate->kind = aggregate->kind;
    211     break;
    212 
    213   case AggregateInst:
    214     newtype->aggInst->aggregate = maybeClone( aggInst->aggregate );
    215     newtype->aggInst->params = maybeClone( aggInst->params );
    216     break;
    217 
    218   case Enum:
    219     newtype->enumeration->name = enumeration->name;
    220     newtype->enumeration->constants = maybeClone( enumeration->constants );
    221     break;
    222 
    223   case Symbolic:
    224   case SymbolicInst:
    225     newtype->symbolic->params = maybeClone( symbolic->params );
    226     newtype->symbolic->actuals = maybeClone( symbolic->actuals );
    227     newtype->symbolic->assertions = maybeClone( symbolic->assertions );
    228     newtype->symbolic->isTypedef = symbolic->isTypedef;
    229     newtype->symbolic->name = symbolic->name;
    230     break;
    231 
    232   case Variable:
    233     newtype->variable->assertions = maybeClone( variable->assertions );
    234     newtype->variable->name = variable->name;
    235     newtype->variable->tyClass = variable->tyClass;
    236     break;
    237 
    238   case Tuple:
    239     newtype->tuple->members = maybeClone( tuple->members );
    240     break;
     141      case Attr:
     142        delete attr->expr;
     143        delete attr->type;
     144        delete attr;
     145        break;
     146    }
     147}
     148
     149TypeData *TypeData::clone() const {
     150    TypeData *newtype = new TypeData( kind );
     151    newtype->qualifiers = qualifiers;
     152    newtype->base = maybeClone( base );
     153    newtype->forall = maybeClone( forall );
     154
     155    switch ( kind ) {
     156      case Unknown:
     157      case EnumConstant:
     158      case Pointer:
     159        // nothing else to copy
     160        break;
     161      case Basic:
     162        newtype->basic->typeSpec = basic->typeSpec;
     163        newtype->basic->modifiers = basic->modifiers;
     164        break;
     165      case Array:
     166        newtype->array->dimension = maybeClone( array->dimension );
     167        newtype->array->isVarLen = array->isVarLen;
     168        newtype->array->isStatic = array->isStatic;
     169        break;
     170      case Function:
     171        newtype->function->params = maybeClone( function->params );
     172        newtype->function->idList = maybeClone( function->idList );
     173        newtype->function->oldDeclList = maybeClone( function->oldDeclList );
     174        newtype->function->body = maybeClone( function->body );
     175        newtype->function->hasBody = function->hasBody;
     176        newtype->function->newStyle = function->newStyle;
     177        break;
     178      case Aggregate:
     179        newtype->aggregate->params = maybeClone( aggregate->params );
     180        newtype->aggregate->actuals = maybeClone( aggregate->actuals );
     181        newtype->aggregate->members = maybeClone( aggregate->members );
     182        newtype->aggregate->name = aggregate->name;
     183        newtype->aggregate->kind = aggregate->kind;
     184        break;
     185      case AggregateInst:
     186        newtype->aggInst->aggregate = maybeClone( aggInst->aggregate );
     187        newtype->aggInst->params = maybeClone( aggInst->params );
     188        break;
     189      case Enum:
     190        newtype->enumeration->name = enumeration->name;
     191        newtype->enumeration->constants = maybeClone( enumeration->constants );
     192        break;
     193      case Symbolic:
     194      case SymbolicInst:
     195        newtype->symbolic->params = maybeClone( symbolic->params );
     196        newtype->symbolic->actuals = maybeClone( symbolic->actuals );
     197        newtype->symbolic->assertions = maybeClone( symbolic->assertions );
     198        newtype->symbolic->isTypedef = symbolic->isTypedef;
     199        newtype->symbolic->name = symbolic->name;
     200        break;
     201      case Variable:
     202        newtype->variable->assertions = maybeClone( variable->assertions );
     203        newtype->variable->name = variable->name;
     204        newtype->variable->tyClass = variable->tyClass;
     205        break;
     206      case Tuple:
     207        newtype->tuple->members = maybeClone( tuple->members );
     208        break;
    241209   
    242   case Typeof:
    243     newtype->typeexpr->expr = maybeClone( typeexpr->expr );
    244     break;
     210      case Typeof:
     211        newtype->typeexpr->expr = maybeClone( typeexpr->expr );
     212        break;
    245213 
    246   case Attr:
    247     newtype->attr->expr = maybeClone( attr->expr );
    248     newtype->attr->type = maybeClone( attr->type );
    249     break;
    250   }
    251   return newtype;
    252 }
    253 
    254 void
    255 TypeData::print( std::ostream &os, int indent ) const
    256 {
    257   using std::endl;
    258   using std::string;
    259 
    260   printEnums( qualifiers.begin(), qualifiers.end(), DeclarationNode::qualifierName, os );
    261 
    262   if( forall ) {
    263     os << "forall " << endl;
    264     forall->printList( os, indent+4 );
    265   }
    266 
    267   switch( kind ) {
    268   case Unknown:
    269     os << "entity of unknown type ";
    270     break;
    271 
    272   case Pointer:
    273     os << "pointer ";
    274     if( base ) {
    275       os << "to ";
    276       base->print( os, indent );
    277     }
    278     break;
    279 
    280   case EnumConstant:
    281     os << "enumeration constant ";
    282     break;
    283 
    284   case Basic:
    285     printEnums( basic->modifiers.begin(), basic->modifiers.end(), DeclarationNode::modifierName, os );
    286     printEnums( basic->typeSpec.begin(), basic->typeSpec.end(), DeclarationNode::basicTypeName, os );
    287     break;
    288 
    289   case Array:
    290     if( array->isStatic ) {
    291       os << "static ";
    292     }
    293     if( array->dimension ) {
    294       os << "array of ";
    295       array->dimension->printOneLine( os, indent );
    296     } else if ( array->isVarLen ) {
    297       os << "variable-length array of ";
    298     } else {
    299       os << "open array of ";
    300     }
    301     if( base ) {
    302       base->print( os, indent );
    303     }
    304     break;
    305 
    306   case Function:
    307     os << "function" << endl;
    308     if ( function->params ) {
    309       os << string( indent+2, ' ' ) << "with parameters " << endl;
    310       function->params->printList( os, indent+4 );
    311     } else {
    312       os << string( indent+2, ' ' ) << "with no parameters " << endl;
    313     }
    314     if ( function->idList ) {
    315       os << string( indent+2, ' ' ) << "with old-style identifier list " << endl;
    316       function->idList->printList( os, indent+4 );
    317     }
    318     if ( function->oldDeclList ) {
    319       os << string( indent+2, ' ' ) << "with old-style declaration list " << endl;
    320       function->oldDeclList->printList( os, indent+4 );
    321     }
    322     os << string( indent+2, ' ' ) << "returning ";
    323     if ( base ) {
    324       base->print( os, indent+4 );
    325     } else {
    326       os << "nothing ";
    327     }
    328     os << endl;
    329     if ( function->hasBody ) {
    330       os << string( indent+2, ' ' ) << "with body " << endl;
    331     }
    332     if ( function->body ) {
    333       function->body->printList( os, indent+2 );
    334     }
    335     break;
    336 
    337   case Aggregate:
    338     os << DeclarationNode::tyConName[ aggregate->kind ] << ' ' << aggregate->name << endl;
    339     if( aggregate->params ) {
    340       os << string( indent+2, ' ' ) << "with type parameters " << endl;
    341       aggregate->params->printList( os, indent+4 );
    342     }
    343     if( aggregate->actuals ) {
    344       os << string( indent+2, ' ' ) << "instantiated with actual parameters " << endl;
    345       aggregate->actuals->printList( os, indent+4 );
    346     }
    347     if( aggregate->members ) {
    348       os << string( indent+2, ' ' ) << "with members " << endl;
    349       aggregate->members->printList( os, indent+4 );
     214      case Attr:
     215        newtype->attr->expr = maybeClone( attr->expr );
     216        newtype->attr->type = maybeClone( attr->type );
     217        break;
     218    }
     219    return newtype;
     220}
     221
     222void TypeData::print( std::ostream &os, int indent ) const {
     223    using std::endl;
     224    using std::string;
     225
     226    printEnums( qualifiers.begin(), qualifiers.end(), DeclarationNode::qualifierName, os );
     227
     228    if ( forall ) {
     229        os << "forall " << endl;
     230        forall->printList( os, indent+4 );
     231    }
     232
     233    switch ( kind ) {
     234      case Unknown:
     235        os << "entity of unknown type ";
     236        break;
     237      case Pointer:
     238        os << "pointer ";
     239        if ( base ) {
     240            os << "to ";
     241            base->print( os, indent );
     242        }
     243        break;
     244      case EnumConstant:
     245        os << "enumeration constant ";
     246        break;
     247      case Basic:
     248        printEnums( basic->modifiers.begin(), basic->modifiers.end(), DeclarationNode::modifierName, os );
     249        printEnums( basic->typeSpec.begin(), basic->typeSpec.end(), DeclarationNode::basicTypeName, os );
     250        break;
     251      case Array:
     252        if ( array->isStatic ) {
     253            os << "static ";
     254        }
     255        if ( array->dimension ) {
     256            os << "array of ";
     257            array->dimension->printOneLine( os, indent );
     258        } else if ( array->isVarLen ) {
     259            os << "variable-length array of ";
     260        } else {
     261            os << "open array of ";
     262        }
     263        if ( base ) {
     264            base->print( os, indent );
     265        }
     266        break;
     267      case Function:
     268        os << "function" << endl;
     269        if ( function->params ) {
     270            os << string( indent+2, ' ' ) << "with parameters " << endl;
     271            function->params->printList( os, indent+4 );
     272        } else {
     273            os << string( indent+2, ' ' ) << "with no parameters " << endl;
     274        }
     275        if ( function->idList ) {
     276            os << string( indent+2, ' ' ) << "with old-style identifier list " << endl;
     277            function->idList->printList( os, indent+4 );
     278        }
     279        if ( function->oldDeclList ) {
     280            os << string( indent+2, ' ' ) << "with old-style declaration list " << endl;
     281            function->oldDeclList->printList( os, indent+4 );
     282        }
     283        os << string( indent+2, ' ' ) << "returning ";
     284        if ( base ) {
     285            base->print( os, indent+4 );
     286        } else {
     287            os << "nothing ";
     288        }
     289        os << endl;
     290        if ( function->hasBody ) {
     291            os << string( indent+2, ' ' ) << "with body " << endl;
     292        }
     293        if ( function->body ) {
     294            function->body->printList( os, indent+2 );
     295        }
     296        break;
     297      case Aggregate:
     298        os << DeclarationNode::tyConName[ aggregate->kind ] << ' ' << aggregate->name << endl;
     299        if ( aggregate->params ) {
     300            os << string( indent+2, ' ' ) << "with type parameters " << endl;
     301            aggregate->params->printList( os, indent+4 );
     302        }
     303        if ( aggregate->actuals ) {
     304            os << string( indent+2, ' ' ) << "instantiated with actual parameters " << endl;
     305            aggregate->actuals->printList( os, indent+4 );
     306        }
     307        if ( aggregate->members ) {
     308            os << string( indent+2, ' ' ) << "with members " << endl;
     309            aggregate->members->printList( os, indent+4 );
    350310///     } else {
    351311///       os << string( indent+2, ' ' ) << "with no members " << endl;
    352     }
    353     break;
    354 
    355   case AggregateInst:
    356     if( aggInst->aggregate ) {
    357       os << "instance of " ;
    358       aggInst->aggregate->print( os, indent );
     312        }
     313        break;
     314      case AggregateInst:
     315        if ( aggInst->aggregate ) {
     316            os << "instance of " ;
     317            aggInst->aggregate->print( os, indent );
     318        } else {
     319            os << "instance of an unspecified aggregate ";
     320        }
     321        if ( aggInst->params ) {
     322            os << string( indent+2, ' ' ) << "with parameters " << endl;
     323            aggInst->params->printList( os, indent+2 );
     324        }
     325        break;
     326      case Enum:
     327        os << "enumeration ";
     328        if ( enumeration->constants ) {
     329            os << "with constants" << endl;
     330            enumeration->constants->printList( os, indent+2 );
     331        }
     332        break;
     333      case SymbolicInst:
     334        os << "instance of type " << symbolic->name;
     335        if ( symbolic->actuals ) {
     336            os << " with parameters" << endl;
     337            symbolic->actuals->printList( os, indent + 2 );
     338        }
     339        break;
     340      case Symbolic:
     341        if ( symbolic->isTypedef ) {
     342            os << "typedef definition ";
     343        } else {
     344            os << "type definition ";
     345        }
     346        if ( symbolic->params ) {
     347            os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
     348            symbolic->params->printList( os, indent + 2 );
     349        }
     350        if ( symbolic->assertions ) {
     351            os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
     352            symbolic->assertions->printList( os, indent + 4 );
     353            os << string( indent+2, ' ' );
     354        }
     355        if ( base ) {
     356            os << "for ";
     357            base->print( os, indent + 2 );
     358        }
     359        break;
     360      case Variable:
     361        os << DeclarationNode::typeClassName[ variable->tyClass ] << " variable ";
     362        if ( variable->assertions ) {
     363            os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
     364            variable->assertions->printList( os, indent + 4 );
     365            os << string( indent+2, ' ' );
     366        }
     367        break;
     368      case Tuple:
     369        os << "tuple ";
     370        if ( tuple->members ) {
     371            os << "with members " << endl;
     372            tuple->members->printList( os, indent + 2 );
     373        }
     374        break;
     375   
     376      case Typeof:
     377        os << "type-of expression ";
     378        if ( typeexpr->expr ) {
     379            typeexpr->expr->print( os, indent + 2 );
     380        }
     381        break;
     382   
     383      case Attr:
     384        os << "attribute type decl " << attr->name << " applied to ";
     385        if ( attr->expr ) {
     386            attr->expr->print( os, indent + 2 );
     387        }
     388        if ( attr->type ) {
     389            attr->type->print( os, indent + 2 );
     390        }
     391        break;
     392    }
     393}
     394
     395TypeData *TypeData::extractAggregate( bool toplevel ) const {
     396    TypeData *ret = 0;
     397
     398    switch ( kind ) {
     399      case Aggregate:
     400        if ( !toplevel && aggregate->members ) {
     401            ret = clone();
     402            ret->qualifiers.clear();
     403        }
     404        break;
     405      case Enum:
     406        if ( !toplevel && enumeration->constants ) {
     407            ret = clone();
     408            ret->qualifiers.clear();
     409        }
     410        break;
     411      case AggregateInst:
     412        if ( aggInst->aggregate ) {
     413            ret = aggInst->aggregate->extractAggregate( false );
     414        }
     415        break;
     416      default:
     417        if ( base ) {
     418            ret = base->extractAggregate( false );
     419        }
     420    }
     421    return ret;
     422}
     423
     424void buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList ) {
     425 
     426    buildList( firstNode, outputList );
     427    for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
     428        if ( (*i)->get_kind() == TypeDecl::Any ) {
     429            FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     430            assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     431            assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
     432            assignType->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
     433            (*i)->get_assertions().push_front( new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::Cforall,  assignType, 0, false ) );
     434        }
     435    }
     436}
     437
     438Declaration *TypeData::buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init ) const {
     439    if ( kind == TypeData::Function ) {
     440        FunctionDecl *decl;
     441        if ( function->hasBody ) {
     442            if ( function->body ) {
     443                Statement *stmt = function->body->build();
     444                CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt );
     445                assert( body );
     446                decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline );
     447            } else {
     448                // std::list<Label> ls;
     449                decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list<Label>() ), isInline );
     450            }
     451        } else {
     452            decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline );
     453        }
     454        for ( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_link() ) ) {
     455            if ( cur->get_name() != "" ) {
     456                decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
     457            }
     458        }
     459        buildList( function->oldDeclList, decl->get_oldDecls() );
     460        return decl;
     461    } else if ( kind == TypeData::Aggregate ) {
     462        return buildAggregate();
     463    } else if ( kind == TypeData::Enum ) {
     464        return buildEnum();
     465    } else if ( kind == TypeData::Symbolic ) {
     466        return buildSymbolic( name, sc );
     467    } else if ( kind == TypeData::Variable ) {
     468        return buildVariable();
    359469    } else {
    360       os << "instance of an unspecified aggregate ";
    361     }
    362     if( aggInst->params ) {
    363       os << string( indent+2, ' ' ) << "with parameters " << endl;
    364       aggInst->params->printList( os, indent+2 );
    365     }
    366     break;
    367 
    368   case Enum:
    369     os << "enumeration ";
    370     if( enumeration->constants ) {
    371       os << "with constants" << endl;
    372       enumeration->constants->printList( os, indent+2 );
    373     }
    374     break;
    375 
    376   case SymbolicInst:
    377     os << "instance of type " << symbolic->name;
    378     if( symbolic->actuals ) {
    379       os << " with parameters" << endl;
    380       symbolic->actuals->printList( os, indent + 2 );
    381     }
    382     break;
    383 
    384   case Symbolic:
    385     if( symbolic->isTypedef ) {
    386       os << "typedef definition ";
     470        if ( isInline ) {
     471            throw SemanticError( "invalid inline specification in declaration of ", this );
     472        } else {
     473            return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init );
     474        }
     475    }
     476    return 0;
     477}
     478
     479Type *TypeData::build() const {
     480
     481    switch ( kind ) {
     482      case Unknown:
     483        // fill in implicit int
     484        return new BasicType( buildQualifiers(), BasicType::SignedInt );
     485
     486      case Basic:
     487        return buildBasicType();
     488
     489      case Pointer:
     490        return buildPointer();
     491
     492      case Array:
     493        return buildArray();
     494
     495      case Function:
     496        return buildFunction();
     497
     498      case AggregateInst:
     499        return buildAggInst();
     500
     501      case EnumConstant:
     502        // the name gets filled in later -- by SymTab::Validate
     503        return new EnumInstType( buildQualifiers(), "" );
     504
     505      case SymbolicInst:
     506        return buildSymbolicInst();;
     507
     508      case Tuple:
     509        return buildTuple();
     510 
     511      case Typeof:
     512        return buildTypeof();
     513
     514      case Attr:
     515        return buildAttr();
     516
     517      case Symbolic:
     518      case Enum:
     519      case Aggregate:
     520      case Variable:
     521        assert( false );
     522    }
     523
     524    return 0;
     525}
     526
     527Type::Qualifiers TypeData::buildQualifiers() const {
     528    Type::Qualifiers q;
     529    for ( std::list< DeclarationNode::Qualifier >::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i ) {
     530        switch ( *i ) {
     531          case DeclarationNode::Const:
     532            q.isConst = true;
     533            break;
     534          case DeclarationNode::Volatile:
     535            q.isVolatile = true;
     536            break;
     537          case DeclarationNode::Restrict:
     538            q.isRestrict = true;
     539            break;
     540          case DeclarationNode::Lvalue:
     541            q.isLvalue = true;
     542            break;
     543        }
     544    }
     545    return q;
     546}
     547
     548Type *TypeData::buildBasicType() const {
     549    static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
     550                                               BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
     551                                               BasicType::DoubleImaginary };
     552    bool init = false;
     553    bool sawDouble = false;
     554    bool sawSigned = false;
     555    BasicType::Kind ret;
     556
     557    for ( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) {
     558        if ( !init ) {
     559            init = true;
     560            if ( *i == DeclarationNode::Void ) {
     561                if ( basic->typeSpec.size() != 1 || !basic->modifiers.empty() ) {
     562                    throw SemanticError( "invalid type specifier \"void\" in type ", this );
     563                } else {
     564                    return new VoidType( buildQualifiers() );
     565                }
     566            } else {
     567                ret = kindMap[ *i ];
     568            }
     569        } else {
     570            switch ( *i ) {
     571              case DeclarationNode::Float:
     572                if ( sawDouble ) {
     573                    throw SemanticError( "invalid type specifier \"float\" in type ", this );
     574                } else {
     575                    switch ( ret ) {
     576                      case BasicType::DoubleComplex:
     577                        ret = BasicType::FloatComplex;
     578                        break;
     579                      case BasicType::DoubleImaginary:
     580                        ret = BasicType::FloatImaginary;
     581                        break;
     582                      default:
     583                        throw SemanticError( "invalid type specifier \"float\" in type ", this );
     584                    }
     585                }
     586                break;
     587              case DeclarationNode::Double:
     588                if ( sawDouble ) {
     589                    throw SemanticError( "duplicate type specifier \"double\" in type ", this );
     590                } else {
     591                    switch ( ret ) {
     592                      case BasicType::DoubleComplex:
     593                      case BasicType::DoubleImaginary:
     594                        break;
     595                      default:
     596                        throw SemanticError( "invalid type specifier \"double\" in type ", this );
     597                    }
     598                }
     599                break;
     600       
     601              case DeclarationNode::Complex:
     602                switch ( ret ) {
     603                  case BasicType::Float:
     604                    ret = BasicType::FloatComplex;
     605                    break;
     606         
     607                  case BasicType::Double:
     608                    ret = BasicType::DoubleComplex;
     609                    break;
     610                  default:
     611                    throw SemanticError( "invalid type specifier \"complex\" in type ", this );
     612                }
     613                break;
     614       
     615              case DeclarationNode::Imaginary:
     616                switch ( ret ) {
     617                  case BasicType::Float:
     618                    ret = BasicType::FloatImaginary;
     619                    break;
     620         
     621                  case BasicType::Double:
     622                    ret = BasicType::DoubleImaginary;
     623                    break;
     624                  default:
     625                    throw SemanticError( "invalid type specifier \"imaginary\" in type ", this );
     626                }
     627                break;
     628       
     629              default:
     630                throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type ", this );
     631            }
     632        }
     633        if ( *i == DeclarationNode::Double ) {
     634            sawDouble = true;
     635        }
     636    }
     637
     638    for ( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) {
     639        switch ( *i ) {
     640          case DeclarationNode::Long:
     641            if ( !init ) {
     642                init = true;
     643                ret = BasicType::LongSignedInt;
     644            } else {
     645                switch ( ret ) {
     646                  case BasicType::SignedInt:
     647                    ret = BasicType::LongSignedInt;
     648                    break;
     649                  case BasicType::UnsignedInt:
     650                    ret = BasicType::LongUnsignedInt;
     651                    break;
     652                  case BasicType::LongSignedInt:
     653                    ret = BasicType::LongLongSignedInt;
     654                    break;
     655                  case BasicType::LongUnsignedInt:
     656                    ret = BasicType::LongLongUnsignedInt;
     657                    break;
     658                  case BasicType::Double:
     659                    ret = BasicType::LongDouble;
     660                    break;
     661                  case BasicType::DoubleComplex:
     662                    ret = BasicType::LongDoubleComplex;
     663                    break;
     664                  case BasicType::DoubleImaginary:
     665                    ret = BasicType::LongDoubleImaginary;
     666                    break;
     667                  default:
     668                    throw SemanticError( "invalid type modifier \"long\" in type ", this );
     669                }
     670            }
     671            break;
     672          case DeclarationNode::Short:
     673            if ( !init ) {
     674                init = true;
     675                ret = BasicType::ShortSignedInt;
     676            } else {
     677                switch ( ret ) {
     678                  case BasicType::SignedInt:
     679                    ret = BasicType::ShortSignedInt;
     680                    break;
     681                  case BasicType::UnsignedInt:
     682                    ret = BasicType::ShortUnsignedInt;
     683                    break;
     684                  default:
     685                    throw SemanticError( "invalid type modifier \"short\" in type ", this );
     686                }
     687            }
     688            break;
     689          case DeclarationNode::Signed:
     690            if ( !init ) {
     691                init = true;
     692                ret = BasicType::SignedInt;
     693            } else if ( sawSigned ) {
     694                throw SemanticError( "duplicate type modifer \"signed\" in type ", this );
     695            } else {
     696                switch ( ret ) {
     697                  case BasicType::SignedInt:
     698                  case BasicType::ShortSignedInt:
     699                    break;
     700                  case BasicType::Char:
     701                    ret = BasicType::SignedChar;
     702                    break;
     703                  default:
     704                    throw SemanticError( "invalid type modifer \"signed\" in type ", this );
     705                }
     706            }
     707            break;
     708          case DeclarationNode::Unsigned:
     709            if ( !init ) {
     710                init = true;
     711                ret = BasicType::UnsignedInt;
     712            } else if ( sawSigned ) {
     713                throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
     714            } else {
     715                switch ( ret ) {
     716                  case BasicType::LongSignedInt:
     717                    ret = BasicType::LongUnsignedInt;
     718                    break;
     719                  case BasicType::SignedInt:
     720                    ret = BasicType::UnsignedInt;
     721                    break;
     722                  case BasicType::ShortSignedInt:
     723                    ret = BasicType::ShortUnsignedInt;
     724                    break;
     725                  case BasicType::Char:
     726                    ret = BasicType::UnsignedChar;
     727                    break;
     728                  default:
     729                    throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
     730                }
     731            }
     732            break;
     733        }
     734
     735        if ( *i == DeclarationNode::Signed ) {
     736            sawSigned = true;
     737        }
     738    }
     739
     740    BasicType *bt;
     741    if ( !init ) {
     742        bt = new BasicType( buildQualifiers(), BasicType::SignedInt );
    387743    } else {
    388       os << "type definition ";
    389     }
    390     if( symbolic->params ) {
    391       os << endl << string( indent+2, ' ' ) << "with parameters" << endl;
    392       symbolic->params->printList( os, indent + 2 );
    393     }
    394     if( symbolic->assertions ) {
    395       os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
    396       symbolic->assertions->printList( os, indent + 4 );
    397       os << string( indent+2, ' ' );
    398     }
    399     if( base ) {
    400       os << "for ";
    401       base->print( os, indent + 2 );
    402     }
    403     break;
    404 
    405   case Variable:
    406     os << DeclarationNode::typeClassName[ variable->tyClass ] << " variable ";
    407     if( variable->assertions ) {
    408       os << endl << string( indent+2, ' ' ) << "with assertions" << endl;
    409       variable->assertions->printList( os, indent + 4 );
    410       os << string( indent+2, ' ' );
    411     }
    412     break;
    413 
    414   case Tuple:
    415     os << "tuple ";
    416     if( tuple->members ) {
    417       os << "with members " << endl;
    418       tuple->members->printList( os, indent + 2 );
    419     }
    420     break;
     744        bt = new BasicType( buildQualifiers(), ret );
     745    }
     746    buildForall( forall, bt->get_forall() );
     747    return bt;
     748}
     749
     750
     751PointerType *TypeData::buildPointer() const {
     752    PointerType *pt;
     753    if ( base ) {
     754        pt = new PointerType( buildQualifiers(), base->build() );
     755    } else {
     756        pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     757    }
     758    buildForall( forall, pt->get_forall() );
     759    return pt;
     760}
     761
     762ArrayType *TypeData::buildArray() const {
     763 
     764    ArrayType *at;
     765    if ( base ) {
     766        at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ),
     767                            array->isVarLen, array->isStatic );
     768    } else {
     769        at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
     770                            maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic );
     771    }
     772    buildForall( forall, at->get_forall() );
     773    return at;
     774}
     775
     776FunctionType *TypeData::buildFunction() const {
     777    assert( kind == Function );
     778    bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true;
     779    if ( !function->params ) hasEllipsis = !function->newStyle;
     780    FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis );
     781    buildList( function->params, ft->get_parameters() );
     782    buildForall( forall, ft->get_forall() );
     783    if ( base ) {
     784        switch ( base->kind ) {
     785          case Tuple:
     786            buildList( base->tuple->members, ft->get_returnVals() );
     787            break;
     788          default:
     789            ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", Declaration::NoStorageClass, 0, false, LinkageSpec::Cforall ) ) );
     790        }
     791    } else {
     792        ft->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
     793    }
     794    return ft;
     795}
     796
     797AggregateDecl *TypeData::buildAggregate() const {
     798    assert( kind == Aggregate );
     799    AggregateDecl *at;
     800    switch ( aggregate->kind ) {
     801      case DeclarationNode::Struct:
     802        at = new StructDecl( aggregate->name );
     803        break;
    421804   
    422   case Typeof:
    423     os << "type-of expression ";
    424     if( typeexpr->expr ) {
    425       typeexpr->expr->print( os, indent + 2 );
    426     }
    427     break;
     805      case DeclarationNode::Union:
     806        at = new UnionDecl( aggregate->name );
     807        break;
    428808   
    429   case Attr:
    430     os << "attribute type decl " << attr->name << " applied to ";
    431     if( attr->expr ) {
    432       attr->expr->print( os, indent + 2 );
    433     }
    434     if( attr->type ) {
    435       attr->type->print( os, indent + 2 );
    436     }
    437     break;
    438   }
    439 }
    440 
    441 TypeData *
    442 TypeData::extractAggregate( bool toplevel ) const
    443 {
    444   TypeData *ret = 0;
    445 
    446   switch( kind ) {
    447   case Aggregate:
    448     if( !toplevel && aggregate->members ) {
    449       ret = clone();
    450       ret->qualifiers.clear();
    451     }
    452     break;
    453 
    454   case Enum:
    455     if( !toplevel && enumeration->constants ) {
    456       ret = clone();
    457       ret->qualifiers.clear();
    458     }
    459     break;
    460 
    461   case AggregateInst:
    462     if( aggInst->aggregate ) {
    463       ret = aggInst->aggregate->extractAggregate( false );
    464     }
    465     break;
    466 
    467   default:
    468     if( base ) {
    469       ret = base->extractAggregate( false );
    470     }
    471   }
    472   return ret;
    473 }
    474 
    475 void
    476 buildForall( const DeclarationNode *firstNode, std::list< TypeDecl* > &outputList )
    477 {
     809      case DeclarationNode::Context:
     810        at = new ContextDecl( aggregate->name );
     811        break;
     812   
     813      default:
     814        assert( false );
     815    }
    478816 
    479   buildList( firstNode, outputList );
    480   for( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
    481     if( (*i)->get_kind() == TypeDecl::Any ) {
    482       FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    483       assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
    484       assignType->get_parameters().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
    485       assignType->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
    486       (*i)->get_assertions().push_front( new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::Cforall,  assignType, 0, false ) );
    487     }
    488   }
    489 }
    490 
    491 Declaration *
    492 TypeData::buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init ) const
    493 {
    494 
    495   if ( kind == TypeData::Function ) {
    496     FunctionDecl *decl;
    497     if( function->hasBody ) {
    498       if( function->body ) {
    499         Statement *stmt = function->body->build();
    500         CompoundStmt *body = dynamic_cast< CompoundStmt* >( stmt );
    501         assert( body );
    502         decl = new FunctionDecl( name, sc, linkage, buildFunction(), body, isInline );
    503       } else {
    504         // std::list<Label> ls;
    505         decl = new FunctionDecl( name, sc, linkage, buildFunction(), new CompoundStmt( std::list<Label>() ), isInline );
    506       }
    507     } else {
    508       decl = new FunctionDecl( name, sc, linkage, buildFunction(), 0, isInline );
    509     }
    510     for( DeclarationNode *cur = function->idList; cur != 0; cur = dynamic_cast< DeclarationNode* >( cur->get_link() ) ) {
    511       if( cur->get_name() != "" ) {
    512         decl->get_oldIdents().insert( decl->get_oldIdents().end(), cur->get_name() );
    513       }
    514     }
    515     buildList( function->oldDeclList, decl->get_oldDecls() );
    516     return decl;
    517   } else if ( kind == TypeData::Aggregate ) {
    518     return buildAggregate();
    519   } else if ( kind == TypeData::Enum ) {
    520     return buildEnum();
    521   } else if ( kind == TypeData::Symbolic ) {
    522     return buildSymbolic( name, sc );
    523   } else if ( kind == TypeData::Variable ) {
    524     return buildVariable();
    525   } else {
    526     if( isInline ) {
    527       throw SemanticError( "invalid inline specification in declaration of ", this );
    528     } else {
    529       return new ObjectDecl( name, sc, linkage, bitfieldWidth, build(), init );
    530     }
    531   }
    532   return 0;
    533 }
    534 
    535 Type *
    536 TypeData::build() const
    537 {
    538 
    539   switch( kind ) {
    540   case Unknown:
    541     // fill in implicit int
    542     return new BasicType( buildQualifiers(), BasicType::SignedInt );
    543 
    544   case Basic:
    545     return buildBasicType();
    546 
    547   case Pointer:
    548     return buildPointer();
    549 
    550   case Array:
    551     return buildArray();
    552 
    553   case Function:
    554     return buildFunction();
    555 
    556   case AggregateInst:
    557     return buildAggInst();
    558 
    559   case EnumConstant:
    560     // the name gets filled in later -- by SymTab::Validate
    561     return new EnumInstType( buildQualifiers(), "" );
    562 
    563   case SymbolicInst:
    564     return buildSymbolicInst();;
    565 
    566   case Tuple:
    567     return buildTuple();
    568  
    569   case Typeof:
    570     return buildTypeof();
    571 
    572   case Attr:
    573     return buildAttr();
    574 
    575   case Symbolic:
    576   case Enum:
    577   case Aggregate:
    578   case Variable:
    579     assert( false );
    580   }
    581 
    582   return 0;
    583 }
    584 
    585 Type::Qualifiers
    586 TypeData::buildQualifiers() const
    587 {
    588   Type::Qualifiers q;
    589   for( std::list< DeclarationNode::Qualifier >::const_iterator i = qualifiers.begin(); i != qualifiers.end(); ++i ) {
    590     switch( *i ) {
    591     case DeclarationNode::Const:
    592       q.isConst = true;
    593       break;
    594 
    595     case DeclarationNode::Volatile:
    596       q.isVolatile = true;
    597       break;
    598 
    599     case DeclarationNode::Restrict:
    600       q.isRestrict = true;
    601       break;
    602 
    603     case DeclarationNode::Lvalue:
    604       q.isLvalue = true;
    605       break;
    606     }
    607   }
    608   return q;
    609 }
    610 
    611 Type*
    612 TypeData::buildBasicType() const
    613 {
    614 
    615   static const BasicType::Kind kindMap[] = { BasicType::Char, BasicType::SignedInt, BasicType::Float, BasicType::Double,
    616                                              BasicType::Char /* void */, BasicType::Bool, BasicType::DoubleComplex,
    617                                              BasicType::DoubleImaginary };
    618 
    619   bool init = false;
    620   bool sawDouble = false;
    621   bool sawSigned = false;
    622   BasicType::Kind ret;
    623 
    624   for( std::list< DeclarationNode::BasicType >::const_iterator i = basic->typeSpec.begin(); i != basic->typeSpec.end(); ++i ) {
    625     if( !init ) {
    626       init = true;
    627       if( *i == DeclarationNode::Void ) {
    628         if( basic->typeSpec.size() != 1 || !basic->modifiers.empty() ) {
    629           throw SemanticError( "invalid type specifier \"void\" in type ", this );
    630         } else {
    631           return new VoidType( buildQualifiers() );
    632         }
    633       } else {
    634         ret = kindMap[ *i ];
    635       }
    636     } else {
    637       switch( *i ) {
    638       case DeclarationNode::Float:
    639         if( sawDouble ) {
    640           throw SemanticError( "invalid type specifier \"float\" in type ", this );
    641         } else {
    642           switch( ret ) {
    643           case BasicType::DoubleComplex:
    644             ret = BasicType::FloatComplex;
    645             break;
    646 
    647           case BasicType::DoubleImaginary:
    648             ret = BasicType::FloatImaginary;
    649             break;
    650 
    651           default:
    652             throw SemanticError( "invalid type specifier \"float\" in type ", this );
    653           }
    654         }
    655         break;
    656 
    657       case DeclarationNode::Double:
    658         if( sawDouble ) {
    659           throw SemanticError( "duplicate type specifier \"double\" in type ", this );
    660         } else {
    661           switch( ret ) {
    662           case BasicType::DoubleComplex:
    663           case BasicType::DoubleImaginary:
    664             break;
    665 
    666           default:
    667             throw SemanticError( "invalid type specifier \"double\" in type ", this );
    668           }
    669         }
    670         break;
    671        
    672       case DeclarationNode::Complex:
    673         switch( ret ) {
    674         case BasicType::Float:
    675           ret = BasicType::FloatComplex;
    676           break;
    677          
    678         case BasicType::Double:
    679           ret = BasicType::DoubleComplex;
    680           break;
    681 
    682         default:
    683           throw SemanticError( "invalid type specifier \"complex\" in type ", this );
    684         }
    685         break;
    686        
    687       case DeclarationNode::Imaginary:
    688         switch( ret ) {
    689         case BasicType::Float:
    690           ret = BasicType::FloatImaginary;
    691           break;
    692          
    693         case BasicType::Double:
    694           ret = BasicType::DoubleImaginary;
    695           break;
    696 
    697         default:
    698           throw SemanticError( "invalid type specifier \"imaginary\" in type ", this );
    699         }
    700         break;
    701        
    702       default:
    703         throw SemanticError( std::string( "invalid type specifier \"" ) + DeclarationNode::basicTypeName[ *i ] + "\" in type ", this );
    704       }
    705     }
    706     if( *i == DeclarationNode::Double ) {
    707       sawDouble = true;
    708     }
    709   }
    710 
    711   for( std::list< DeclarationNode::Modifier >::const_iterator i = basic->modifiers.begin(); i != basic->modifiers.end(); ++i ) {
    712     switch( *i ) {
    713     case DeclarationNode::Long:
    714       if( !init ) {
    715         init = true;
    716         ret = BasicType::LongSignedInt;
    717       } else {
    718         switch( ret ) {
    719         case BasicType::SignedInt:
    720           ret = BasicType::LongSignedInt;
    721           break;
    722 
    723         case BasicType::UnsignedInt:
    724           ret = BasicType::LongUnsignedInt;
    725           break;
    726 
    727         case BasicType::LongSignedInt:
    728           ret = BasicType::LongLongSignedInt;
    729           break;
    730 
    731         case BasicType::LongUnsignedInt:
    732           ret = BasicType::LongLongUnsignedInt;
    733           break;
    734 
    735         case BasicType::Double:
    736           ret = BasicType::LongDouble;
    737           break;
    738 
    739         case BasicType::DoubleComplex:
    740           ret = BasicType::LongDoubleComplex;
    741           break;
    742 
    743         case BasicType::DoubleImaginary:
    744           ret = BasicType::LongDoubleImaginary;
    745           break;
    746 
    747         default:
    748           throw SemanticError( "invalid type modifier \"long\" in type ", this );
    749         }
    750       }
    751       break;
    752 
    753     case DeclarationNode::Short:
    754       if( !init ) {
    755         init = true;
    756         ret = BasicType::ShortSignedInt;
    757       } else {
    758         switch( ret ) {
    759         case BasicType::SignedInt:
    760           ret = BasicType::ShortSignedInt;
    761           break;
    762 
    763         case BasicType::UnsignedInt:
    764           ret = BasicType::ShortUnsignedInt;
    765           break;
    766 
    767         default:
    768           throw SemanticError( "invalid type modifier \"short\" in type ", this );
    769         }
    770       }
    771       break;
    772 
    773     case DeclarationNode::Signed:
    774       if( !init ) {
    775         init = true;
    776         ret = BasicType::SignedInt;
    777       } else if( sawSigned ) {
    778         throw SemanticError( "duplicate type modifer \"signed\" in type ", this );
    779       } else {
    780         switch( ret ) {
    781         case BasicType::SignedInt:
    782         case BasicType::ShortSignedInt:
    783           break;
    784 
    785         case BasicType::Char:
    786           ret = BasicType::SignedChar;
    787           break;
    788 
    789         default:
    790           throw SemanticError( "invalid type modifer \"signed\" in type ", this );
    791         }
    792       }
    793       break;
    794 
    795     case DeclarationNode::Unsigned:
    796       if( !init ) {
    797         init = true;
    798         ret = BasicType::UnsignedInt;
    799       } else if( sawSigned ) {
    800         throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
    801       } else {
    802         switch( ret ) {
    803         case BasicType::LongSignedInt:
    804           ret = BasicType::LongUnsignedInt;
    805           break;
    806 
    807         case BasicType::SignedInt:
    808           ret = BasicType::UnsignedInt;
    809           break;
    810 
    811         case BasicType::ShortSignedInt:
    812           ret = BasicType::ShortUnsignedInt;
    813           break;
    814 
    815         case BasicType::Char:
    816           ret = BasicType::UnsignedChar;
    817           break;
    818 
    819         default:
    820           throw SemanticError( "invalid type modifer \"unsigned\" in type ", this );
    821         }
    822       }
    823       break;
    824     }
    825 
    826     if( *i == DeclarationNode::Signed ) {
    827       sawSigned = true;
    828     }
    829   }
    830 
    831   BasicType *bt;
    832   if( !init ) {
    833     bt = new BasicType( buildQualifiers(), BasicType::SignedInt );
    834   } else {
    835     bt = new BasicType( buildQualifiers(), ret );
    836   }
    837   buildForall( forall, bt->get_forall() );
    838   return bt;
    839 }
    840 
    841 
    842 PointerType *
    843 TypeData::buildPointer() const
    844 {
    845  
    846   PointerType *pt;
    847   if( base ) {
    848     pt = new PointerType( buildQualifiers(), base->build() );
    849   } else {
    850     pt = new PointerType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    851   }
    852   buildForall( forall, pt->get_forall() );
    853   return pt;
    854 }
    855 
    856 ArrayType *
    857 TypeData::buildArray() const
    858 {
    859  
    860   ArrayType *at;
    861   if( base ) {
    862     at = new ArrayType( buildQualifiers(), base->build(), maybeBuild< Expression >( array->dimension ),
    863                           array->isVarLen, array->isStatic );
    864   } else {
    865     at = new ArrayType( buildQualifiers(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
    866                           maybeBuild< Expression >( array->dimension ), array->isVarLen, array->isStatic );
    867   }
    868   buildForall( forall, at->get_forall() );
    869   return at;
    870 }
    871 
    872 FunctionType *
    873 TypeData::buildFunction() const
    874 {
    875   assert( kind == Function );
    876 
    877 
    878   bool hasEllipsis = function->params ? function->params->get_hasEllipsis() : true;
    879   if( !function->params ) hasEllipsis = !function->newStyle;
    880   FunctionType *ft = new FunctionType( buildQualifiers(), hasEllipsis );
    881   buildList( function->params, ft->get_parameters() );
    882   buildForall( forall, ft->get_forall() );
    883   if( base ) {
    884     switch( base->kind ) {
    885     case Tuple:
    886       buildList( base->tuple->members, ft->get_returnVals() );
    887       break;
    888 
    889     default:
    890       ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType* >( base->buildDecl( "", Declaration::NoStorageClass, 0, false, LinkageSpec::Cforall ) ) );
    891     }
    892   } else {
    893     ft->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ) );
    894   }
    895   return ft;
    896 }
    897 
    898 AggregateDecl *
    899 TypeData::buildAggregate() const
    900 {
    901   assert( kind == Aggregate );
    902 
    903 
    904   AggregateDecl *at;
    905   switch( aggregate->kind ) {
    906   case DeclarationNode::Struct:
    907     at = new StructDecl( aggregate->name );
    908     break;
    909    
    910   case DeclarationNode::Union:
    911     at = new UnionDecl( aggregate->name );
    912     break;
    913    
    914   case DeclarationNode::Context:
    915     at = new ContextDecl( aggregate->name );
    916     break;
    917    
    918   default:
    919     assert( false );
    920   }
    921  
    922   buildList( aggregate->params, at->get_parameters() );
    923   buildList( aggregate->members, at->get_members() );
    924 
    925   return at;
     817    buildList( aggregate->params, at->get_parameters() );
     818    buildList( aggregate->members, at->get_members() );
     819
     820    return at;
    926821}
    927822
     
    930825/// makeType( Declaration* decl )
    931826/// {
    932 ///   if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     827///   if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
    933828///     return dwt->get_type()->clone();
    934829///   } else {
     
    938833/// }
    939834
    940 ReferenceToType *
    941 TypeData::buildAggInst() const
    942 {
    943   assert( kind == AggregateInst );
    944 
    945 
    946   std::string name;
    947 
    948   ReferenceToType *ret;
    949   if( aggInst->aggregate->kind == Enum ) {
    950     ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name );
    951   } else {
    952     assert( aggInst->aggregate->kind == Aggregate );
    953     switch( aggInst->aggregate->aggregate->kind ) {
    954     case DeclarationNode::Struct:
    955       ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
    956       break;
    957 
    958     case DeclarationNode::Union:
    959       ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
    960       break;
    961 
    962     case DeclarationNode::Context:
    963       ret = new ContextInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
    964       break;
    965 
    966     default:
    967       assert( false );
    968     }
    969   }
    970   buildList( aggInst->params, ret->get_parameters() );
    971   buildForall( forall, ret->get_forall() );
    972   return ret;
    973 }
    974 
    975 NamedTypeDecl*
    976 TypeData::buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const
    977 {
    978   assert( kind == Symbolic );
    979 
    980 
    981   NamedTypeDecl *ret;
    982   if( symbolic->isTypedef ) {
    983     ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) );
    984   } else {
    985     ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any );
    986   }
    987   buildList( symbolic->params, ret->get_parameters() );
    988   buildList( symbolic->assertions, ret->get_assertions() );
    989   return ret;
    990 }
    991 
    992 TypeDecl*
    993 TypeData::buildVariable() const
    994 {
    995   assert( kind == Variable );
    996 
    997 
    998   static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
    999 
    1000   TypeDecl *ret = new TypeDecl( variable->name, Declaration::NoStorageClass, 0, kindMap[ variable->tyClass ] );
    1001   buildList( variable->assertions, ret->get_assertions() );
     835ReferenceToType *TypeData::buildAggInst() const {
     836    assert( kind == AggregateInst );
     837    std::string name;
     838
     839    ReferenceToType *ret;
     840    if ( aggInst->aggregate->kind == Enum ) {
     841        ret = new EnumInstType( buildQualifiers(), aggInst->aggregate->enumeration->name );
     842    } else {
     843        assert( aggInst->aggregate->kind == Aggregate );
     844        switch ( aggInst->aggregate->aggregate->kind ) {
     845          case DeclarationNode::Struct:
     846            ret = new StructInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
     847            break;
     848          case DeclarationNode::Union:
     849            ret = new UnionInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
     850            break;
     851          case DeclarationNode::Context:
     852            ret = new ContextInstType( buildQualifiers(), aggInst->aggregate->aggregate->name );
     853            break;
     854          default:
     855            assert( false );
     856        }
     857    }
     858    buildList( aggInst->params, ret->get_parameters() );
     859    buildForall( forall, ret->get_forall() );
     860    return ret;
     861}
     862
     863NamedTypeDecl *TypeData::buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const {
     864    assert( kind == Symbolic );
     865    NamedTypeDecl *ret;
     866    if ( symbolic->isTypedef ) {
     867        ret = new TypedefDecl( name, sc, maybeBuild< Type >( base ) );
     868    } else {
     869        ret = new TypeDecl( name, sc, maybeBuild< Type >( base ), TypeDecl::Any );
     870    }
     871    buildList( symbolic->params, ret->get_parameters() );
     872    buildList( symbolic->assertions, ret->get_assertions() );
     873    return ret;
     874}
     875
     876TypeDecl *TypeData::buildVariable() const {
     877    assert( kind == Variable );
     878    static const TypeDecl::Kind kindMap[] = { TypeDecl::Any, TypeDecl::Ftype, TypeDecl::Dtype };
     879
     880    TypeDecl *ret = new TypeDecl( variable->name, Declaration::NoStorageClass, 0, kindMap[ variable->tyClass ] );
     881    buildList( variable->assertions, ret->get_assertions() );
    1002882   
    1003   return ret;
    1004 }
    1005 
    1006 EnumDecl*
    1007 TypeData::buildEnum() const
    1008 {
    1009   assert( kind == Enum );
    1010 
    1011 
    1012   EnumDecl *ret = new EnumDecl( enumeration->name );
    1013   buildList( enumeration->constants, ret->get_members() );
    1014 
    1015   return ret;
    1016 }
    1017 
    1018 TypeInstType *
    1019 TypeData::buildSymbolicInst() const
    1020 {
    1021   assert( kind == SymbolicInst );
    1022 
    1023 
    1024   TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name, false );
    1025   buildList( symbolic->actuals, ret->get_parameters() );
    1026   buildForall( forall, ret->get_forall() );
    1027 
    1028   return ret;
    1029 }
    1030 
    1031 TupleType *
    1032 TypeData::buildTuple() const
    1033 {
    1034   assert( kind == Tuple );
    1035 
    1036 
    1037   TupleType *ret = new TupleType( buildQualifiers() );
    1038   buildTypeList( tuple->members, ret->get_types() );
    1039   buildForall( forall, ret->get_forall() );
    1040 
    1041   return ret;
    1042 }
    1043 
    1044 TypeofType *
    1045 TypeData::buildTypeof() const
    1046 {
    1047   assert( kind == Typeof );
    1048 
    1049 
    1050   assert( typeexpr );
    1051   assert( typeexpr->expr );
    1052   TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() );
    1053 
    1054   return ret;
    1055 }
    1056 
    1057 AttrType *
    1058 TypeData::buildAttr() const
    1059 {
    1060   assert( kind == Attr );
    1061 
    1062 
    1063   assert( attr );
    1064   AttrType *ret;
    1065   if( attr->expr ) {
    1066     ret = new AttrType( buildQualifiers(), attr->name, attr->expr->build() );
    1067   } else {
    1068     assert( attr->type );
    1069     ret = new AttrType( buildQualifiers(), attr->name, attr->type->buildType() );
    1070   }
    1071 
    1072   return ret;
    1073 }
    1074 
     883    return ret;
     884}
     885
     886EnumDecl *TypeData::buildEnum() const {
     887    assert( kind == Enum );
     888    EnumDecl *ret = new EnumDecl( enumeration->name );
     889    buildList( enumeration->constants, ret->get_members() );
     890
     891    return ret;
     892}
     893
     894TypeInstType *TypeData::buildSymbolicInst() const {
     895    assert( kind == SymbolicInst );
     896
     897
     898    TypeInstType *ret = new TypeInstType( buildQualifiers(), symbolic->name, false );
     899    buildList( symbolic->actuals, ret->get_parameters() );
     900    buildForall( forall, ret->get_forall() );
     901
     902    return ret;
     903}
     904
     905TupleType *TypeData::buildTuple() const {
     906    assert( kind == Tuple );
     907
     908
     909    TupleType *ret = new TupleType( buildQualifiers() );
     910    buildTypeList( tuple->members, ret->get_types() );
     911    buildForall( forall, ret->get_forall() );
     912
     913    return ret;
     914}
     915
     916TypeofType *TypeData::buildTypeof() const {
     917    assert( kind == Typeof );
     918    assert( typeexpr );
     919    assert( typeexpr->expr );
     920    TypeofType *ret = new TypeofType( buildQualifiers(), typeexpr->expr->build() );
     921
     922    return ret;
     923}
     924
     925AttrType *TypeData::buildAttr() const {
     926    assert( kind == Attr );
     927    assert( attr );
     928    AttrType *ret;
     929    if ( attr->expr ) {
     930        ret = new AttrType( buildQualifiers(), attr->name, attr->expr->build() );
     931    } else {
     932        assert( attr->type );
     933        ret = new AttrType( buildQualifiers(), attr->name, attr->type->buildType() );
     934    }
     935
     936    return ret;
     937}
  • translator/Parser/TypeData.h

    r8c17ab0 rc8ffe20b  
    1010#include "LinkageSpec.h"
    1111
    12 struct TypeData
    13 {
    14   enum Kind { Unknown, Basic, Pointer, Array, Function, Aggregate, AggregateInst,
    15               Enum, EnumConstant, Symbolic, SymbolicInst, Variable, Tuple, Typeof, Attr } kind;
     12struct TypeData {
     13    enum Kind { Unknown, Basic, Pointer, Array, Function, Aggregate, AggregateInst,
     14                Enum, EnumConstant, Symbolic, SymbolicInst, Variable, Tuple, Typeof, Attr } kind;
    1615
    17   TypeData( Kind k = Unknown );
    18   ~TypeData();
    19   void print( std::ostream &, int indent = 0 ) const;
    20   TypeData *clone() const;
     16    TypeData( Kind k = Unknown );
     17    ~TypeData();
     18    void print( std::ostream &, int indent = 0 ) const;
     19    TypeData *clone() const;
    2120
    22   Type *build() const;
    23   FunctionType *buildFunction() const;
     21    Type *build() const;
     22    FunctionType *buildFunction() const;
    2423
    25   TypeData *base;
    26   std::list< DeclarationNode::Qualifier > qualifiers;
    27   DeclarationNode *forall;
     24    TypeData *base;
     25    std::list< DeclarationNode::Qualifier > qualifiers;
     26    DeclarationNode *forall;
    2827
    29   struct Basic_t {
    30     std::list< DeclarationNode::BasicType > typeSpec;
    31     std::list< DeclarationNode::Modifier > modifiers;
    32   };
     28    struct Basic_t {
     29        std::list< DeclarationNode::BasicType > typeSpec;
     30        std::list< DeclarationNode::Modifier > modifiers;
     31    };
    3332
    34   struct Aggregate_t {
    35     DeclarationNode::TyCon kind;
    36     std::string name;
    37     DeclarationNode *params;
    38     ExpressionNode *actuals;    // holds actual parameters that will later be applied to AggInst
    39     DeclarationNode *members;
    40   };
     33    struct Aggregate_t {
     34        DeclarationNode::TyCon kind;
     35        std::string name;
     36        DeclarationNode *params;
     37        ExpressionNode *actuals;                        // holds actual parameters later applied to AggInst
     38        DeclarationNode *members;
     39    };
    4140
    42   struct AggInst_t {
    43     TypeData *aggregate;
    44     ExpressionNode *params;
    45   };
     41    struct AggInst_t {
     42        TypeData *aggregate;
     43        ExpressionNode *params;
     44    };
    4645
    47   struct Array_t {
    48     ExpressionNode *dimension;
    49     bool isVarLen;
    50     bool isStatic;
    51   };
     46    struct Array_t {
     47        ExpressionNode *dimension;
     48        bool isVarLen;
     49        bool isStatic;
     50    };
    5251
    53   struct Enumeration_t {
    54     std::string name;
    55     DeclarationNode *constants;
    56   };
     52    struct Enumeration_t {
     53        std::string name;
     54        DeclarationNode *constants;
     55    };
    5756
    58   struct Function_t {
    59     DeclarationNode *params;
    60     DeclarationNode *idList; // old-style
    61     DeclarationNode *oldDeclList;
    62     StatementNode *body;
    63     bool hasBody;
    64     bool newStyle;
    65   };
     57    struct Function_t {
     58        DeclarationNode *params;
     59        DeclarationNode *idList;                        // old-style
     60        DeclarationNode *oldDeclList;
     61        StatementNode *body;
     62        bool hasBody;
     63        bool newStyle;
     64    };
    6665
    67   struct Symbolic_t {
    68     std::string name;
    69     bool isTypedef;
    70     DeclarationNode *params;
    71     ExpressionNode *actuals;
    72     DeclarationNode *assertions;
    73   };
     66    struct Symbolic_t {
     67        std::string name;
     68        bool isTypedef;
     69        DeclarationNode *params;
     70        ExpressionNode *actuals;
     71        DeclarationNode *assertions;
     72    };
    7473
    75   struct Variable_t {
    76     DeclarationNode::TypeClass tyClass;
    77     std::string name;
    78     DeclarationNode *assertions;
    79   };
     74    struct Variable_t {
     75        DeclarationNode::TypeClass tyClass;
     76        std::string name;
     77        DeclarationNode *assertions;
     78    };
    8079
    81   struct Tuple_t {
    82     DeclarationNode *members;
    83   };
     80    struct Tuple_t {
     81        DeclarationNode *members;
     82    };
    8483 
    85   struct Typeof_t {
    86     ExpressionNode *expr;
    87   };
     84    struct Typeof_t {
     85        ExpressionNode *expr;
     86    };
    8887
    89   struct Attr_t {
    90     std::string name;
    91     ExpressionNode *expr;
    92     DeclarationNode *type;
    93   };
     88    struct Attr_t {
     89        std::string name;
     90        ExpressionNode *expr;
     91        DeclarationNode *type;
     92    };
    9493
    95   union {
    96     Basic_t *basic;
    97     Aggregate_t *aggregate;
    98     AggInst_t *aggInst;
    99     Array_t *array;
    100     Enumeration_t *enumeration;
    101     Function_t *function;
    102     Symbolic_t *symbolic;
    103     Variable_t *variable;
    104     Tuple_t *tuple;
    105     Typeof_t *typeexpr;
    106     Attr_t *attr;
    107   };
     94    union {
     95        Basic_t *basic;
     96        Aggregate_t *aggregate;
     97        AggInst_t *aggInst;
     98        Array_t *array;
     99        Enumeration_t *enumeration;
     100        Function_t *function;
     101        Symbolic_t *symbolic;
     102        Variable_t *variable;
     103        Tuple_t *tuple;
     104        Typeof_t *typeexpr;
     105        Attr_t *attr;
     106    };
    108107
    109   TypeData *extractAggregate( bool toplevel = true ) const;
    110   /* helper function for DeclNodeImpl::build */
    111   Declaration * buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init = 0 ) const;
    112   /* helper functions for build() */
    113   Type::Qualifiers buildQualifiers() const;
    114   Type *buildBasicType() const;
    115   PointerType * buildPointer() const;
    116   ArrayType * buildArray() const;
    117   AggregateDecl * buildAggregate() const;
    118   ReferenceToType * buildAggInst() const;
    119   NamedTypeDecl * buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const;
    120   TypeDecl* buildVariable() const;
    121   EnumDecl* buildEnum() const;
    122   TypeInstType * buildSymbolicInst() const;
    123   TupleType * buildTuple() const;
    124   TypeofType * buildTypeof() const;
    125   AttrType * buildAttr() const;
     108    TypeData *extractAggregate( bool toplevel = true ) const;
     109    // helper function for DeclNodeImpl::build
     110    Declaration * buildDecl( std::string name, Declaration::StorageClass sc, Expression *bitfieldWidth, bool isInline, LinkageSpec::Type linkage, Initializer *init = 0 ) const;
     111    // helper functions for build()
     112    Type::Qualifiers buildQualifiers() const;
     113    Type *buildBasicType() const;
     114    PointerType * buildPointer() const;
     115    ArrayType * buildArray() const;
     116    AggregateDecl * buildAggregate() const;
     117    ReferenceToType * buildAggInst() const;
     118    NamedTypeDecl * buildSymbolic( const std::string &name, Declaration::StorageClass sc ) const;
     119    TypeDecl* buildVariable() const;
     120    EnumDecl* buildEnum() const;
     121    TypeInstType * buildSymbolicInst() const;
     122    TupleType * buildTuple() const;
     123    TypeofType * buildTypeof() const;
     124    AttrType * buildAttr() const;
    126125};
    127126
    128 #endif /* #ifndef TYPEDATA_H */
     127#endif // TYPEDATA_H
  • translator/Parser/TypedefTable.h

    r8c17ab0 rc8ffe20b  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: TypedefTable.h,v 1.5 2003/05/11 15:24:05 rcbilson Exp $
    5  *
    6  */
    7 
    81#ifndef TYPEDEFTABLE_H
    92#define TYPEDEFTABLE_H
     
    147#include <stack>
    158
    16 class TypedefTable
    17 {
     9class TypedefTable {
    1810  public:
    1911    enum kind_t { ID, TD, TG };
    2012  private:
    21     struct Entry
    22     {
     13    struct Entry {
    2314        int scope;
    2415        kind_t kind;
    2516    };
    2617   
    27     struct DeferredEntry
    28     {
    29       std::string identifier;
    30       kind_t kind;
     18    struct DeferredEntry {
     19        std::string identifier;
     20        kind_t kind;
    3121    };
    3222
     
    4434    std::stack< std::string > nextIdentifiers;
    4535
    46     bool isKind(std::string identifier, kind_t kind) const;
    47     void addToScope(const std::string &identifier, kind_t kind, int scope);
     36    bool isKind( std::string identifier, kind_t kind ) const;
     37    void addToScope( const std::string &identifier, kind_t kind, int scope );
    4838  public:
    4939    TypedefTable();
    5040
    51     bool isIdentifier(std::string identifier) const;
    52     bool isTypedef(std::string identifier) const;
    53     bool isTypegen(std::string identifier) const;
     41    bool isIdentifier( std::string identifier ) const;
     42    bool isTypedef( std::string identifier ) const;
     43    bool isTypegen( std::string identifier ) const;
    5444   
    55     // "addToCurrentScope" adds the identifier/type pair to the current scope This does less
    56     // than you think it does, since each declaration is within its own scope.  Mostly useful for
    57     // type parameters.
    58     void addToCurrentScope(const std::string &identifier, kind_t kind);
    59     void addToCurrentScope(kind_t kind);   // use nextIdentifiers.top()
     45    // "addToCurrentScope" adds the identifier/type pair to the current scope This does less than you think it does,
     46    // since each declaration is within its own scope.  Mostly useful for type parameters.
     47    void addToCurrentScope( const std::string &identifier, kind_t kind );
     48    void addToCurrentScope( kind_t kind );              // use nextIdentifiers.top()
    6049
    61     // "addToEnclosingScope" adds the identifier/type pair to the scope that encloses the current
    62     // one.  This is the right way to handle type and typedef names
    63     void addToEnclosingScope(const std::string &identifier, kind_t kind);
    64     void addToEnclosingScope(kind_t kind); // use nextIdentifiers.top()
     50    // "addToEnclosingScope" adds the identifier/type pair to the scope that encloses the current one.  This is the
     51    // right way to handle type and typedef names
     52    void addToEnclosingScope( const std::string &identifier, kind_t kind );
     53    void addToEnclosingScope( kind_t kind );            // use nextIdentifiers.top()
    6554   
    66     // "addToEnclosingScope2" adds the identifier/type pair to the scope that encloses the scope
    67     // enclosing the the current one.  This is the right way to handle assertion names
    68     void addToEnclosingScope2(const std::string &identifier, kind_t kind);
    69     void addToEnclosingScope2(kind_t kind); // use nextIdentifiers.top()
     55    // "addToEnclosingScope2" adds the identifier/type pair to the scope that encloses the scope enclosing the the
     56    // current one.  This is the right way to handle assertion names
     57    void addToEnclosingScope2( const std::string &identifier, kind_t kind );
     58    void addToEnclosingScope2( kind_t kind );           // use nextIdentifiers.top()
    7059   
    71     // set the next identifier to be used by an "add" operation without an identifier parameter
    72     // within the current scope
     60    // set the next identifier to be used by an "add" operation without an identifier parameter within the current scope
    7361    void setNextIdentifier( const std::string &identifier );
    7462   
     
    7664    void openContext( std::string contextName );
    7765   
    78     void enterScope(void);
    79     void leaveScope(void);
     66    void enterScope( void );
     67    void leaveScope( void );
    8068    void enterContext( std::string contextName );
    81     void leaveContext(void);
     69    void leaveContext( void );
    8270
    83     void print(void) const;
     71    void print( void ) const;
    8472};
    8573
    86 #endif /* ifndef TYPEDEFTABLE_H */
     74#endif // TYPEDEFTABLE_H
  • translator/SymTab/Validate.cc

    r8c17ab0 rc8ffe20b  
    11/*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Validate.cc,v 1.22 2005/08/29 20:14:18 rcbilson Exp $
    5  *
    6  */
    7 
    8 /*
    9    The "validate" phase of translation is used to take a syntax tree and convert it into a
    10    standard form that aims to be as regular in structure as possible.  Some assumptions can be
    11    made regarding the state of the tree after this pass is complete, including:
    12 
    13    - No nested structure or union definitions; any in the input are "hoisted" to the level of
    14      the containing struct or union.
    15 
    16    - All enumeration constants have type EnumInstType.
    17 
    18    - The type "void" never occurs in lists of function parameter or return types; neither do
    19      tuple types.  A function taking no arguments has no argument types, and tuples are flattened.
    20 
    21    - No context instances exist; they are all replaced by the set of declarations signified by
    22      the context, instantiated by the particular set of type arguments.
    23 
    24    - Every declaration is assigned a unique id.
    25 
    26    - No typedef declarations or instances exist; the actual type is substituted for each instance.
    27 
    28    - Each type, struct, and union definition is followed by an appropriate assignment operator.
    29 
    30    - Each use of a struct or union is connected to a complete definition of that struct or union,
    31      even if that definition occurs later in the input.
     2  The "validate" phase of translation is used to take a syntax tree and convert it into a
     3  standard form that aims to be as regular in structure as possible.  Some assumptions can be
     4  made regarding the state of the tree after this pass is complete, including:
     5
     6  - No nested structure or union definitions; any in the input are "hoisted" to the level of
     7  the containing struct or union.
     8
     9  - All enumeration constants have type EnumInstType.
     10
     11  - The type "void" never occurs in lists of function parameter or return types; neither do
     12  tuple types.  A function taking no arguments has no argument types, and tuples are flattened.
     13
     14  - No context instances exist; they are all replaced by the set of declarations signified by
     15  the context, instantiated by the particular set of type arguments.
     16
     17  - Every declaration is assigned a unique id.
     18
     19  - No typedef declarations or instances exist; the actual type is substituted for each instance.
     20
     21  - Each type, struct, and union definition is followed by an appropriate assignment operator.
     22
     23  - Each use of a struct or union is connected to a complete definition of that struct or union,
     24  even if that definition occurs later in the input.
    3225*/
    3326
     
    4841
    4942
    50 #define debugPrint(x) if( doDebug ) { std::cout << x; }
     43#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
    5144
    5245namespace SymTab {
    53 
    54 class HoistStruct : public Visitor
    55 {
    56 public:
    57   static void hoistStruct( std::list< Declaration* > &translationUnit );
    58  
    59   std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
    60  
    61   virtual void visit(StructDecl *aggregateDecl);
    62   virtual void visit(UnionDecl *aggregateDecl);
    63 
    64   virtual void visit(CompoundStmt *compoundStmt);
    65   virtual void visit(IfStmt *ifStmt);
    66   virtual void visit(WhileStmt *whileStmt);
    67   virtual void visit(ForStmt *forStmt);
    68   virtual void visit(SwitchStmt *switchStmt);
    69   virtual void visit(ChooseStmt *chooseStmt);
    70   virtual void visit(CaseStmt *caseStmt);
    71   virtual void visit(CatchStmt *catchStmt);
    72  
    73 private:
    74   HoistStruct();
    75 
    76   template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    77 
    78   std::list< Declaration* > declsToAdd;
    79   bool inStruct;
    80 };
    81 
    82 class Pass1 : public Visitor
    83 {
    84   typedef Visitor Parent;
    85   virtual void visit( EnumDecl *aggregateDecl);
    86   virtual void visit( FunctionType *func );
    87 };
    88  
    89 class Pass2 : public Indexer
    90 {
    91   typedef Indexer Parent;
    92 
    93 public:
    94   Pass2( bool doDebug, const Indexer *indexer );
    95 
    96 private:
    97   virtual void visit( StructInstType *structInst );
    98   virtual void visit( UnionInstType *unionInst );
    99   virtual void visit( ContextInstType *contextInst );
    100   virtual void visit( StructDecl *structDecl );
    101   virtual void visit( UnionDecl *unionDecl );
    102   virtual void visit( TypeInstType *typeInst );
    103 
    104   const Indexer *indexer;
    105  
    106   typedef std::map< std::string, std::list< StructInstType* > > ForwardStructsType;
    107   typedef std::map< std::string, std::list< UnionInstType* > > ForwardUnionsType;
    108   ForwardStructsType forwardStructs;
    109   ForwardUnionsType forwardUnions;
    110 };
    111 
    112 class Pass3 : public Indexer
    113 {
    114   typedef Indexer Parent;
    115 
    116 public:
    117   Pass3( const Indexer *indexer );
    118 
    119 private:
    120   virtual void visit( ObjectDecl *object );
    121   virtual void visit( FunctionDecl *func );
    122 
    123   const Indexer *indexer;
    124 };
    125 
    126 class AddStructAssignment : public Visitor
    127 {
    128 public:
    129   static void addStructAssignment( std::list< Declaration* > &translationUnit );
    130 
    131   std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
    132  
    133   virtual void visit( StructDecl *structDecl );
    134   virtual void visit( UnionDecl *structDecl );
    135   virtual void visit( TypeDecl *typeDecl );
    136   virtual void visit( ContextDecl *ctxDecl );
    137 
    138   virtual void visit( FunctionType *ftype );
    139   virtual void visit( PointerType *ftype );
    140  
    141   virtual void visit(CompoundStmt *compoundStmt);
    142   virtual void visit(IfStmt *ifStmt);
    143   virtual void visit(WhileStmt *whileStmt);
    144   virtual void visit(ForStmt *forStmt);
    145   virtual void visit(SwitchStmt *switchStmt);
    146   virtual void visit(ChooseStmt *chooseStmt);
    147   virtual void visit(CaseStmt *caseStmt);
    148   virtual void visit(CatchStmt *catchStmt);
    149  
    150 private:
    151   template< typename StmtClass > void visitStatement(StmtClass *stmt);
    152  
    153   std::list< Declaration* > declsToAdd;
    154   std::set< std::string > structsDone;
    155 };
    156 
    157 class EliminateTypedef : public Mutator
    158 {
    159 public:
    160   static void eliminateTypedef( std::list< Declaration* > &translationUnit );
    161  
    162 private:
    163   virtual Declaration* mutate(TypedefDecl *typeDecl);
    164   virtual TypeDecl* mutate(TypeDecl *typeDecl);
    165   virtual DeclarationWithType* mutate(FunctionDecl *funcDecl);
    166   virtual ObjectDecl* mutate(ObjectDecl *objDecl);
    167   virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
    168   virtual Type* mutate(TypeInstType *aggregateUseType);
    169   virtual Expression* mutate(CastExpr *castExpr);
    170  
    171   std::map< std::string, TypedefDecl* > typedefNames;
    172 };
    173 
    174 void
    175 validate( std::list< Declaration* > &translationUnit, bool doDebug, const Indexer *indexer )
    176 {
    177   Pass1 pass1;
    178   Pass2 pass2( doDebug, indexer );
    179   Pass3 pass3( indexer );
    180   EliminateTypedef::eliminateTypedef( translationUnit );
    181   HoistStruct::hoistStruct( translationUnit );
    182   acceptAll( translationUnit, pass1 );
    183   acceptAll( translationUnit, pass2 );
    184   AddStructAssignment::addStructAssignment( translationUnit );
    185   acceptAll( translationUnit, pass3 );
    186 }
    187 
    188 void
    189 validateType( Type *type, const Indexer *indexer )
    190 {
    191   Pass1 pass1;
    192   Pass2 pass2( false, indexer );
    193   Pass3 pass3( indexer );
    194   type->accept( pass1 );
    195   type->accept( pass2 );
    196   type->accept( pass3 );
    197 }
    198 
    199 template< typename Visitor >
    200 void
    201 acceptAndAdd( std::list< Declaration* > &translationUnit, Visitor &visitor, bool addBefore )
    202 {
    203   std::list< Declaration* >::iterator i = translationUnit.begin();
    204   while( i != translationUnit.end() ) {
    205     (*i)->accept( visitor );
    206     std::list< Declaration* >::iterator next = i;
    207     next++;
    208     if( !visitor.get_declsToAdd().empty() ) {
    209       translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
    210     }
    211     i = next;
    212   }
    213 }
    214 
    215 /* static class method */
    216 void
    217 HoistStruct::hoistStruct( std::list< Declaration* > &translationUnit )
    218 {
    219   HoistStruct hoister;
    220   acceptAndAdd( translationUnit, hoister, true );
    221 }
    222 
    223 HoistStruct::HoistStruct()
    224   : inStruct( false )
    225 {
    226 }
    227 
    228 void
    229 filter( std::list< Declaration* > &declList, bool (*pred)( Declaration* ), bool doDelete )
    230 {
    231   std::list< Declaration* >::iterator i = declList.begin();
    232   while( i != declList.end() ) {
    233     std::list< Declaration* >::iterator next = i;
    234     ++next;
    235     if( pred( *i ) ) {
    236       if( doDelete ) {
    237         delete *i;
    238       }
    239       declList.erase( i );
    240     }
    241     i = next;
    242   }
    243 }
    244 
    245 bool
    246 isStructOrUnion( Declaration *decl )
    247 {
    248   return dynamic_cast< StructDecl* >( decl ) || dynamic_cast< UnionDecl* >( decl );
    249 }
    250 
    251 template< typename AggDecl >
    252 void
    253 HoistStruct::handleAggregate( AggDecl *aggregateDecl )
    254 {
    255   if( inStruct ) {
    256     declsToAdd.push_back( aggregateDecl );
    257     Visitor::visit( aggregateDecl );
    258   } else {
    259     inStruct = true;
    260     Visitor::visit( aggregateDecl );
    261     inStruct = false;
    262     filter( aggregateDecl->get_members(), isStructOrUnion, false );
    263   }
    264 }
    265 
    266 void
    267 HoistStruct::visit(StructDecl *aggregateDecl)
    268 {
    269   handleAggregate( aggregateDecl );
    270 }
    271 
    272 void
    273 HoistStruct::visit(UnionDecl *aggregateDecl)
    274 {
    275   handleAggregate( aggregateDecl );
    276 }
    277 
    278 void
    279 HoistStruct::visit(CompoundStmt *compoundStmt)
    280 {
    281   addVisit( compoundStmt, *this );
    282 }
    283 
    284 void
    285 HoistStruct::visit(IfStmt *ifStmt)
    286 {
    287   addVisit( ifStmt, *this );
    288 }
    289 
    290 void
    291 HoistStruct::visit(WhileStmt *whileStmt)
    292 {
    293   addVisit( whileStmt, *this );
    294 }
    295 
    296 void
    297 HoistStruct::visit(ForStmt *forStmt)
    298 {
    299   addVisit( forStmt, *this );
    300 }
    301 
    302 void
    303 HoistStruct::visit(SwitchStmt *switchStmt)
    304 {
    305   addVisit( switchStmt, *this );
    306 }
    307 
    308 void
    309 HoistStruct::visit(ChooseStmt *switchStmt)
    310 {
    311   addVisit( switchStmt, *this );
    312 }
    313 
    314 void
    315 HoistStruct::visit(CaseStmt *caseStmt)
    316 {
    317   addVisit( caseStmt, *this );
    318 }
    319 
    320 void
    321 HoistStruct::visit(CatchStmt *cathStmt)
    322 {
    323   addVisit( cathStmt, *this );
    324 }
    325 
    326 void
    327 Pass1::visit( EnumDecl *enumDecl)
    328 {
    329   // Set the type of each member of the enumeration to be EnumConstant
    330  
    331   for( std::list< Declaration* >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    332     ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    333     assert( obj );
    334     obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) );
    335   }
    336   Parent::visit( enumDecl );
    337 }
    338 
    339 namespace {
    340 template< typename DWTIterator >
    341 void
    342 fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func )
    343 {
    344   // the only case in which "void" is valid is where it is the only one in the list; then
    345   // it should be removed entirely
    346   // other fix ups are handled by the FixFunction class
    347   if( begin == end ) return;
    348   FixFunction fixer;
    349   DWTIterator i = begin;
    350   *i = (*i)->acceptMutator( fixer );
    351   if( fixer.get_isVoid() ) {
    352     DWTIterator j = i;
    353     ++i;
    354     func->get_parameters().erase( j );
    355     if( i != end ) {
    356       throw SemanticError( "invalid type void in function type ", func );
    357     }
    358   } else {
    359     ++i;
    360     for( ; i != end; ++i ) {
    361       FixFunction fixer;
    362       *i = (*i)->acceptMutator( fixer );
    363       if( fixer.get_isVoid() ) {
    364         throw SemanticError( "invalid type void in function type ", func );
    365       }
    366     }
    367   }
    368 }
    369 }
    370 
    371 void
    372 Pass1::visit( FunctionType *func )
    373 {
    374   // Fix up parameters and return types
    375   fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
    376   fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
    377   Visitor::visit( func );
    378 }
    379 
    380 Pass2::Pass2( bool doDebug, const Indexer *other_indexer )
    381   : Indexer( doDebug )
    382 {
    383   if( other_indexer ) {
    384     indexer = other_indexer;
    385   } else {
    386     indexer = this;
    387   }
    388 }
    389 
    390 void
    391 Pass2::visit( StructInstType *structInst )
    392 {
    393   Parent::visit( structInst );
    394   StructDecl *st = indexer->lookupStruct( structInst->get_name() );
    395   // it's not a semantic error if the struct is not found, just an implicit forward declaration
    396   if( st ) {
    397     assert( !structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || !st->get_members().empty() );
    398     structInst->set_baseStruct( st );
    399   }
    400   if( !st || st->get_members().empty() ) {
    401     // use of forward declaration
    402     forwardStructs[ structInst->get_name() ].push_back( structInst );
    403   }
    404 }
    405 
    406 void
    407 Pass2::visit( UnionInstType *unionInst )
    408 {
    409   Parent::visit( unionInst );
    410   UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
    411   // it's not a semantic error if the union is not found, just an implicit forward declaration
    412   if( un ) {
    413     unionInst->set_baseUnion( un );
    414   }
    415   if( !un || un->get_members().empty() ) {
    416     // use of forward declaration
    417     forwardUnions[ unionInst->get_name() ].push_back( unionInst );
    418   }
    419 }
    420 
    421 void
    422 Pass2::visit( ContextInstType *contextInst )
    423 {
    424   Parent::visit( contextInst );
    425   ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
    426   if( !ctx ) {
    427     throw SemanticError( "use of undeclared context " + contextInst->get_name() );
    428   }
    429   for( std::list< TypeDecl* >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    430     for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
    431       if( ContextInstType *otherCtx = dynamic_cast< ContextInstType* >(*assert) ) {
    432         cloneAll( otherCtx->get_members(), contextInst->get_members() );
    433       } else {
    434         contextInst->get_members().push_back( (*assert)->clone() );
    435       }
    436     }
    437   }
    438   applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) );
    439 }
    440 
    441 void
    442 Pass2::visit( StructDecl *structDecl )
    443 {
    444   if( !structDecl->get_members().empty() ) {
    445     ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
    446     if( fwds != forwardStructs.end() ) {
    447       for( std::list< StructInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    448         (*inst)->set_baseStruct( structDecl );
    449       }
    450       forwardStructs.erase( fwds );
    451     }
    452   }
    453   Indexer::visit( structDecl );
    454 }
    455 
    456 void
    457 Pass2::visit( UnionDecl *unionDecl )
    458 {
    459   if( !unionDecl->get_members().empty() ) {
    460     ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
    461     if( fwds != forwardUnions.end() ) {
    462       for( std::list< UnionInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    463         (*inst)->set_baseUnion( unionDecl );
    464       }
    465       forwardUnions.erase( fwds );
    466     }
    467   }
    468   Indexer::visit( unionDecl );
    469 }
    470 
    471 void
    472 Pass2::visit( TypeInstType *typeInst )
    473 {
    474   if( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
    475     if( TypeDecl *typeDecl = dynamic_cast< TypeDecl* >( namedTypeDecl ) ) {
    476       typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
    477     }
    478   }
    479 }
    480 
    481 Pass3::Pass3( const Indexer *other_indexer )
    482   : Indexer( false )
    483 {
    484   if( other_indexer ) {
    485     indexer = other_indexer;
    486   } else {
    487     indexer = this;
    488   }
    489 }
    490 
    491 void
    492 forallFixer( Type *func )
    493 {
    494   // Fix up assertions
    495   for( std::list< TypeDecl* >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
    496     std::list< DeclarationWithType* > toBeDone, nextRound;
    497     toBeDone.splice( toBeDone.end(), (*type)->get_assertions() );
    498     while( !toBeDone.empty() ) {
    499       for( std::list< DeclarationWithType* >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    500         if( ContextInstType *ctx = dynamic_cast< ContextInstType* >( (*assertion)->get_type() ) ) {
    501           for( std::list< Declaration* >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    502             DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i );
    503             assert( dwt );
    504             nextRound.push_back( dwt->clone() );
    505           }
    506           delete ctx;
    507         } else {
    508           FixFunction fixer;
    509           *assertion = (*assertion)->acceptMutator( fixer );
    510           if( fixer.get_isVoid() ) {
    511             throw SemanticError( "invalid type void in assertion of function ", func );
    512           }
    513           (*type)->get_assertions().push_back( *assertion );
    514         }
    515       }
    516       toBeDone.clear();
    517       toBeDone.splice( toBeDone.end(), nextRound );
    518     }
    519   }
    520 }
    521 
    522 void
    523 Pass3::visit( ObjectDecl *object )
    524 {
    525   forallFixer( object->get_type() );
    526   if( PointerType *pointer = dynamic_cast< PointerType* >( object->get_type() ) ) {
    527     forallFixer( pointer->get_base() );
    528   }
    529   Parent::visit( object );
    530   object->fixUniqueId();
    531 }
    532 
    533 void
    534 Pass3::visit( FunctionDecl *func )
    535 {
    536   forallFixer( func->get_type() );
    537   Parent::visit( func );
    538   func->fixUniqueId();
    539 }
    540 
    541 static const std::list< std::string > noLabels;
    542 
    543 /* static class method */
    544 void
    545 AddStructAssignment::addStructAssignment( std::list< Declaration* > &translationUnit )
    546 {
    547   AddStructAssignment visitor;
    548   acceptAndAdd( translationUnit, visitor, false );
    549 }
    550 
    551 template< typename OutputIterator >
    552 void
    553 makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out )
    554 {
    555   ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); // PAB: unnamed bit fields are not copied
    556   if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    557 
    558   UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    559  
    560   UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    561   derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    562  
    563   // do something special for unnamed members
    564   Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    565   assignExpr->get_args().push_back( dstselect );
    566  
    567   Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    568   assignExpr->get_args().push_back( srcselect );
    569  
    570   *out++ = new ExprStmt( noLabels, assignExpr );
    571 }
    572 
    573 template< typename OutputIterator >
    574 void
    575 makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out )
    576 {
    577   static UniqueName indexName( "_index" );
    578  
    579   // for a flexible array member nothing is done -- user must define own assignment
    580   if( !array->get_dimension() ) return;
    581  
    582   ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    583   *out++ = new DeclStmt( noLabels, index );
    584  
    585   UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    586   init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    587   init->get_args().push_back( new NameExpr( "0" ) );
    588   Statement *initStmt = new ExprStmt( noLabels, init );
    589  
    590   UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    591   cond->get_args().push_back( new VariableExpr( index ) );
    592   cond->get_args().push_back( array->get_dimension()->clone() );
    593  
    594   UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    595   inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    596  
    597   UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    598  
    599   UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    600   derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    601  
    602   Expression *dstselect = new MemberExpr( member, derefExpr );
    603   UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
    604   dstIndex->get_args().push_back( dstselect );
    605   dstIndex->get_args().push_back( new VariableExpr( index ) );
    606   assignExpr->get_args().push_back( dstIndex );
    607  
    608   Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    609   UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    610   srcIndex->get_args().push_back( srcselect );
    611   srcIndex->get_args().push_back( new VariableExpr( index ) );
    612   assignExpr->get_args().push_back( srcIndex );
    613  
    614   *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    615 }
    616 
    617 Declaration*
    618 makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType )
    619 {
    620   FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    621  
    622   ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    623   assignType->get_returnVals().push_back( returnVal );
    624  
    625   ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    626   assignType->get_parameters().push_back( dstParam );
    627  
    628   ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    629   assignType->get_parameters().push_back( srcParam );
    630  
    631   FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
    632   assignDecl->fixUniqueId();
    633  
    634   for( std::list< Declaration* >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    635     if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *member ) ) {
    636       if( ArrayType *array = dynamic_cast< ArrayType* >( dwt->get_type() ) ) {
    637         makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    638       } else {
    639         makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    640       }
    641     }
    642   }
    643   assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    644  
    645   return assignDecl;
    646 }
    647 
    648 Declaration*
    649 makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType )
    650 {
    651   FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    652  
    653   ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    654   assignType->get_returnVals().push_back( returnVal );
    655  
    656   ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    657   assignType->get_parameters().push_back( dstParam );
    658  
    659   ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    660   assignType->get_parameters().push_back( srcParam );
    661  
    662   FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
    663   assignDecl->fixUniqueId();
    664  
    665   UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    666   copy->get_args().push_back( new VariableExpr( dstParam ) );
    667   copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    668   copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
    669 
    670   assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
    671   assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    672  
    673   return assignDecl;
    674 }
    675 
    676 void
    677 AddStructAssignment::visit( StructDecl *structDecl )
    678 {
    679   if( !structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    680     StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
    681     structInst->set_baseStruct( structDecl );
    682     declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
    683     structsDone.insert( structDecl->get_name() );
    684   }
    685 }
    686 
    687 void
    688 AddStructAssignment::visit( UnionDecl *unionDecl )
    689 {
    690   if( !unionDecl->get_members().empty() ) {
    691     UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
    692     unionInst->set_baseUnion( unionDecl );
    693     declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
    694   }
    695 }
    696 
    697 void
    698 AddStructAssignment::visit( TypeDecl *typeDecl )
    699 {
    700   CompoundStmt *stmts = 0;
    701   TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    702   typeInst->set_baseType( typeDecl );
    703   ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
    704   ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
    705   if( typeDecl->get_base() ) {
    706     stmts = new CompoundStmt( std::list< Label >() );
    707     UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    708     assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    709     assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    710     stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
    711   }
    712   FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    713   type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
    714   type->get_parameters().push_back( dst );
    715   type->get_parameters().push_back( src );
    716   FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
    717   declsToAdd.push_back( func );
    718 }
    719 
    720 void
    721 addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i )
    722 {
    723   if( !declsToAdd.empty() ) {
    724     for( std::list< Declaration* >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    725       statements.insert( i, new DeclStmt( noLabels, *decl ) );
    726     }
    727     declsToAdd.clear();
    728   }
    729 }
    730 
    731 void
    732 AddStructAssignment::visit(FunctionType *)
    733 {
    734   // ensure that we don't add assignment ops for types defined
    735   // as part of the function
    736 }
    737 
    738 void
    739 AddStructAssignment::visit(PointerType *)
    740 {
    741   // ensure that we don't add assignment ops for types defined
    742   // as part of the pointer
    743 }
    744 
    745 void
    746 AddStructAssignment::visit(ContextDecl *)
    747 {
    748   // ensure that we don't add assignment ops for types defined
    749   // as part of the context
    750 }
    751 
    752 template< typename StmtClass >
    753 inline void
    754 AddStructAssignment::visitStatement(StmtClass *stmt)
    755 {
    756   std::set< std::string > oldStructs = structsDone;
    757   addVisit( stmt, *this );
    758   structsDone = oldStructs;
    759 }
    760 
    761 void
    762 AddStructAssignment::visit(CompoundStmt *compoundStmt)
    763 {
    764   visitStatement( compoundStmt );
    765 }
    766 
    767 void
    768 AddStructAssignment::visit(IfStmt *ifStmt)
    769 {
    770   visitStatement( ifStmt );
    771 }
    772 
    773 void
    774 AddStructAssignment::visit(WhileStmt *whileStmt)
    775 {
    776   visitStatement( whileStmt );
    777 }
    778 
    779 void
    780 AddStructAssignment::visit(ForStmt *forStmt)
    781 {
    782   visitStatement( forStmt );
    783 }
    784 
    785 void
    786 AddStructAssignment::visit(SwitchStmt *switchStmt)
    787 {
    788   visitStatement( switchStmt );
    789 }
    790 
    791 void
    792 AddStructAssignment::visit(ChooseStmt *switchStmt)
    793 {
    794   visitStatement( switchStmt );
    795 }
    796 
    797 void
    798 AddStructAssignment::visit(CaseStmt *caseStmt)
    799 {
    800   visitStatement( caseStmt );
    801 }
    802 
    803 void
    804 AddStructAssignment::visit(CatchStmt *cathStmt)
    805 {
    806   visitStatement( cathStmt );
    807 }
    808 
    809 bool
    810 isTypedef( Declaration *decl )
    811 {
    812   return dynamic_cast< TypedefDecl* >( decl );
    813 }
    814 
    815 
    816 /* static class method */
    817 void
    818 EliminateTypedef::eliminateTypedef( std::list< Declaration* > &translationUnit )
    819 {
    820   EliminateTypedef eliminator;
    821   mutateAll( translationUnit, eliminator );
    822   filter( translationUnit, isTypedef, true );
    823 }
    824 
    825 Type*
    826 EliminateTypedef::mutate( TypeInstType *typeInst )
    827 {
    828   std::map< std::string, TypedefDecl* >::const_iterator def = typedefNames.find( typeInst->get_name() );
    829   if( def != typedefNames.end() ) {
    830     Type *ret = def->second->get_base()->clone();
    831     ret->get_qualifiers() += typeInst->get_qualifiers();
    832     delete typeInst;
    833     return ret;
    834   }
    835   return typeInst;
    836 }
    837 
    838 Declaration*
    839 EliminateTypedef::mutate( TypedefDecl *tyDecl )
    840 {
    841   Declaration *ret = Mutator::mutate( tyDecl );
    842   typedefNames[ tyDecl->get_name() ] = tyDecl;
    843   if( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl* >( tyDecl->get_base() ) ) {
    844     tyDecl->set_base( 0 );
    845     delete tyDecl;
    846     return aggDecl;
    847   } else {
    848     return ret;
    849   }
    850 }
    851 
    852 TypeDecl*
    853 EliminateTypedef::mutate(TypeDecl *typeDecl)
    854 {
    855   std::map< std::string, TypedefDecl* >::iterator i = typedefNames.find( typeDecl->get_name() );
    856   if( i != typedefNames.end() ) {
    857     typedefNames.erase( i ) ;
    858   }
    859   return typeDecl;
    860 }
    861 
    862 DeclarationWithType*
    863 EliminateTypedef::mutate(FunctionDecl *funcDecl)
    864 {
    865   std::map< std::string, TypedefDecl* > oldNames = typedefNames;
    866   DeclarationWithType *ret = Mutator::mutate( funcDecl );
    867   typedefNames = oldNames;
    868   return ret;
    869 }
    870 
    871 ObjectDecl*
    872 EliminateTypedef::mutate(ObjectDecl *objDecl)
    873 {
    874   std::map< std::string, TypedefDecl* > oldNames = typedefNames;
    875   ObjectDecl *ret = Mutator::mutate( objDecl );
    876   typedefNames = oldNames;
    877   return ret;
    878 }
    879 
    880 Expression*
    881 EliminateTypedef::mutate(CastExpr *castExpr)
    882 {
    883   std::map< std::string, TypedefDecl* > oldNames = typedefNames;
    884   Expression *ret = Mutator::mutate( castExpr );
    885   typedefNames = oldNames;
    886   return ret;
    887 }
    888 
    889 CompoundStmt *
    890 EliminateTypedef::mutate( CompoundStmt *compoundStmt )
    891 {
    892   std::map< std::string, TypedefDecl* > oldNames = typedefNames;
    893   CompoundStmt *ret = Mutator::mutate( compoundStmt );
    894   std::list< Statement* >::iterator i = compoundStmt->get_kids().begin();
    895   while( i != compoundStmt->get_kids().end() ) {
    896     std::list< Statement* >::iterator next = i;
    897     ++next;
    898     if( DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *i ) ) {
    899       if( dynamic_cast< TypedefDecl* >( declStmt->get_decl() ) ) {
    900         delete *i;
    901         compoundStmt->get_kids().erase( i );
    902       }
    903     }
    904     i = next;
    905   }
    906   typedefNames = oldNames;
    907   return ret;
    908 }
    909 
     46    class HoistStruct : public Visitor {
     47      public:
     48        static void hoistStruct( std::list< Declaration * > &translationUnit );
     49 
     50        std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     51 
     52        virtual void visit( StructDecl *aggregateDecl );
     53        virtual void visit( UnionDecl *aggregateDecl );
     54
     55        virtual void visit( CompoundStmt *compoundStmt );
     56        virtual void visit( IfStmt *ifStmt );
     57        virtual void visit( WhileStmt *whileStmt );
     58        virtual void visit( ForStmt *forStmt );
     59        virtual void visit( SwitchStmt *switchStmt );
     60        virtual void visit( ChooseStmt *chooseStmt );
     61        virtual void visit( CaseStmt *caseStmt );
     62        virtual void visit( CatchStmt *catchStmt );
     63      private:
     64        HoistStruct();
     65
     66        template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
     67
     68        std::list< Declaration * > declsToAdd;
     69        bool inStruct;
     70    };
     71
     72    class Pass1 : public Visitor {
     73        typedef Visitor Parent;
     74        virtual void visit( EnumDecl *aggregateDecl );
     75        virtual void visit( FunctionType *func );
     76    };
     77 
     78    class Pass2 : public Indexer {
     79        typedef Indexer Parent;
     80      public:
     81        Pass2( bool doDebug, const Indexer *indexer );
     82      private:
     83        virtual void visit( StructInstType *structInst );
     84        virtual void visit( UnionInstType *unionInst );
     85        virtual void visit( ContextInstType *contextInst );
     86        virtual void visit( StructDecl *structDecl );
     87        virtual void visit( UnionDecl *unionDecl );
     88        virtual void visit( TypeInstType *typeInst );
     89
     90        const Indexer *indexer;
     91 
     92        typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
     93        typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     94        ForwardStructsType forwardStructs;
     95        ForwardUnionsType forwardUnions;
     96    };
     97
     98    class Pass3 : public Indexer {
     99        typedef Indexer Parent;
     100      public:
     101        Pass3( const Indexer *indexer );
     102      private:
     103        virtual void visit( ObjectDecl *object );
     104        virtual void visit( FunctionDecl *func );
     105
     106        const Indexer *indexer;
     107    };
     108
     109    class AddStructAssignment : public Visitor {
     110      public:
     111        static void addStructAssignment( std::list< Declaration * > &translationUnit );
     112
     113        std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     114 
     115        virtual void visit( StructDecl *structDecl );
     116        virtual void visit( UnionDecl *structDecl );
     117        virtual void visit( TypeDecl *typeDecl );
     118        virtual void visit( ContextDecl *ctxDecl );
     119
     120        virtual void visit( FunctionType *ftype );
     121        virtual void visit( PointerType *ftype );
     122 
     123        virtual void visit( CompoundStmt *compoundStmt );
     124        virtual void visit( IfStmt *ifStmt );
     125        virtual void visit( WhileStmt *whileStmt );
     126        virtual void visit( ForStmt *forStmt );
     127        virtual void visit( SwitchStmt *switchStmt );
     128        virtual void visit( ChooseStmt *chooseStmt );
     129        virtual void visit( CaseStmt *caseStmt );
     130        virtual void visit( CatchStmt *catchStmt );
     131      private:
     132        template< typename StmtClass > void visitStatement( StmtClass *stmt );
     133 
     134        std::list< Declaration * > declsToAdd;
     135        std::set< std::string > structsDone;
     136    };
     137
     138    class EliminateTypedef : public Mutator {
     139      public:
     140        static void eliminateTypedef( std::list< Declaration * > &translationUnit );
     141      private:
     142        virtual Declaration *mutate( TypedefDecl *typeDecl );
     143        virtual TypeDecl *mutate( TypeDecl *typeDecl );
     144        virtual DeclarationWithType *mutate( FunctionDecl *funcDecl );
     145        virtual ObjectDecl *mutate( ObjectDecl *objDecl );
     146        virtual CompoundStmt *mutate( CompoundStmt *compoundStmt );
     147        virtual Type *mutate( TypeInstType *aggregateUseType );
     148        virtual Expression *mutate( CastExpr *castExpr );
     149 
     150        std::map< std::string, TypedefDecl * > typedefNames;
     151    };
     152
     153    void validate( std::list< Declaration * > &translationUnit, bool doDebug, const Indexer *indexer ) {
     154        Pass1 pass1;
     155        Pass2 pass2( doDebug, indexer );
     156        Pass3 pass3( indexer );
     157        EliminateTypedef::eliminateTypedef( translationUnit );
     158        HoistStruct::hoistStruct( translationUnit );
     159        acceptAll( translationUnit, pass1 );
     160        acceptAll( translationUnit, pass2 );
     161        AddStructAssignment::addStructAssignment( translationUnit );
     162        acceptAll( translationUnit, pass3 );
     163    }
     164
     165    void validateType( Type *type, const Indexer *indexer ) {
     166        Pass1 pass1;
     167        Pass2 pass2( false, indexer );
     168        Pass3 pass3( indexer );
     169        type->accept( pass1 );
     170        type->accept( pass2 );
     171        type->accept( pass3 );
     172    }
     173
     174    template< typename Visitor >
     175    void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
     176        std::list< Declaration * >::iterator i = translationUnit.begin();
     177        while ( i != translationUnit.end() ) {
     178            (*i )->accept( visitor );
     179            std::list< Declaration * >::iterator next = i;
     180            next++;
     181            if ( ! visitor.get_declsToAdd().empty() ) {
     182                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     183            }
     184            i = next;
     185        }
     186    }
     187
     188    void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
     189        HoistStruct hoister;
     190        acceptAndAdd( translationUnit, hoister, true );
     191    }
     192
     193    HoistStruct::HoistStruct()
     194        : inStruct( false ) {
     195    }
     196
     197    void filter( std::list< Declaration * > &declList, bool (*pred )( Declaration * ), bool doDelete ) {
     198        std::list< Declaration * >::iterator i = declList.begin();
     199        while ( i != declList.end() ) {
     200            std::list< Declaration * >::iterator next = i;
     201            ++next;
     202            if ( pred( *i ) ) {
     203                if ( doDelete ) {
     204                    delete *i;
     205                }
     206                declList.erase( i );
     207            }
     208            i = next;
     209        }
     210    }
     211
     212    bool
     213    isStructOrUnion( Declaration *decl ) {
     214        return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
     215    }
     216
     217    template< typename AggDecl >
     218    void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
     219        if ( inStruct ) {
     220            declsToAdd.push_back( aggregateDecl );
     221            Visitor::visit( aggregateDecl );
     222        } else {
     223            inStruct = true;
     224            Visitor::visit( aggregateDecl );
     225            inStruct = false;
     226            filter( aggregateDecl->get_members(), isStructOrUnion, false );
     227        }
     228    }
     229
     230    void HoistStruct::visit( StructDecl *aggregateDecl ) {
     231        handleAggregate( aggregateDecl );
     232    }
     233
     234    void HoistStruct::visit( UnionDecl *aggregateDecl ) {
     235        handleAggregate( aggregateDecl );
     236    }
     237
     238    void HoistStruct::visit( CompoundStmt *compoundStmt ) {
     239        addVisit( compoundStmt, *this );
     240    }
     241
     242    void HoistStruct::visit( IfStmt *ifStmt ) {
     243        addVisit( ifStmt, *this );
     244    }
     245
     246    void HoistStruct::visit( WhileStmt *whileStmt ) {
     247        addVisit( whileStmt, *this );
     248    }
     249
     250    void HoistStruct::visit( ForStmt *forStmt ) {
     251        addVisit( forStmt, *this );
     252    }
     253
     254    void HoistStruct::visit( SwitchStmt *switchStmt ) {
     255        addVisit( switchStmt, *this );
     256    }
     257
     258    void HoistStruct::visit( ChooseStmt *switchStmt ) {
     259        addVisit( switchStmt, *this );
     260    }
     261
     262    void HoistStruct::visit( CaseStmt *caseStmt ) {
     263        addVisit( caseStmt, *this );
     264    }
     265
     266    void HoistStruct::visit( CatchStmt *cathStmt ) {
     267        addVisit( cathStmt, *this );
     268    }
     269
     270    void Pass1::visit( EnumDecl *enumDecl ) {
     271        // Set the type of each member of the enumeration to be EnumConstant
     272 
     273        for( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     274            ObjectDecl *obj = dynamic_cast< ObjectDecl * >( *i );
     275            assert( obj );
     276            obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) );
     277        }
     278        Parent::visit( enumDecl );
     279    }
     280
     281    namespace {
     282        template< typename DWTIterator >
     283        void
     284        fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) {
     285            // the only case in which "void" is valid is where it is the only one in the list; then
     286            // it should be removed entirely
     287            // other fix ups are handled by the FixFunction class
     288            if ( begin == end ) return;
     289            FixFunction fixer;
     290            DWTIterator i = begin;
     291            *i = (*i )->acceptMutator( fixer );
     292            if ( fixer.get_isVoid() ) {
     293                DWTIterator j = i;
     294                ++i;
     295                func->get_parameters().erase( j );
     296                if ( i != end ) {
     297                    throw SemanticError( "invalid type void in function type ", func );
     298                }
     299            } else {
     300                ++i;
     301                for( ; i != end; ++i ) {
     302                    FixFunction fixer;
     303                    *i = (*i )->acceptMutator( fixer );
     304                    if ( fixer.get_isVoid() ) {
     305                        throw SemanticError( "invalid type void in function type ", func );
     306                    }
     307                }
     308            }
     309        }
     310    }
     311
     312    void Pass1::visit( FunctionType *func ) {
     313        // Fix up parameters and return types
     314        fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
     315        fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
     316        Visitor::visit( func );
     317    }
     318
     319    Pass2::Pass2( bool doDebug, const Indexer *other_indexer )
     320        : Indexer( doDebug ) {
     321        if ( other_indexer ) {
     322            indexer = other_indexer;
     323        } else {
     324            indexer = this;
     325        }
     326    }
     327
     328    void Pass2::visit( StructInstType *structInst ) {
     329        Parent::visit( structInst );
     330        StructDecl *st = indexer->lookupStruct( structInst->get_name() );
     331        // it's not a semantic error if the struct is not found, just an implicit forward declaration
     332        if ( st ) {
     333            assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
     334            structInst->set_baseStruct( st );
     335        }
     336        if ( ! st || st->get_members().empty() ) {
     337            // use of forward declaration
     338            forwardStructs[ structInst->get_name() ].push_back( structInst );
     339        }
     340    }
     341
     342    void Pass2::visit( UnionInstType *unionInst ) {
     343        Parent::visit( unionInst );
     344        UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
     345        // it's not a semantic error if the union is not found, just an implicit forward declaration
     346        if ( un ) {
     347            unionInst->set_baseUnion( un );
     348        }
     349        if ( ! un || un->get_members().empty() ) {
     350            // use of forward declaration
     351            forwardUnions[ unionInst->get_name() ].push_back( unionInst );
     352        }
     353    }
     354
     355    void Pass2::visit( ContextInstType *contextInst ) {
     356        Parent::visit( contextInst );
     357        ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
     358        if ( ! ctx ) {
     359            throw SemanticError( "use of undeclared context " + contextInst->get_name() );
     360        }
     361        for( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
     362            for( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
     363                if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {
     364                    cloneAll( otherCtx->get_members(), contextInst->get_members() );
     365                } else {
     366                    contextInst->get_members().push_back( (*assert )->clone() );
     367                }
     368            }
     369        }
     370        applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) );
     371    }
     372
     373    void Pass2::visit( StructDecl *structDecl ) {
     374        if ( ! structDecl->get_members().empty() ) {
     375            ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     376            if ( fwds != forwardStructs.end() ) {
     377                for( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
     378                    (*inst )->set_baseStruct( structDecl );
     379                }
     380                forwardStructs.erase( fwds );
     381            }
     382        }
     383        Indexer::visit( structDecl );
     384    }
     385
     386    void Pass2::visit( UnionDecl *unionDecl ) {
     387        if ( ! unionDecl->get_members().empty() ) {
     388            ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     389            if ( fwds != forwardUnions.end() ) {
     390                for( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
     391                    (*inst )->set_baseUnion( unionDecl );
     392                }
     393                forwardUnions.erase( fwds );
     394            }
     395        }
     396        Indexer::visit( unionDecl );
     397    }
     398
     399    void Pass2::visit( TypeInstType *typeInst ) {
     400        if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
     401            if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
     402                typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
     403            }
     404        }
     405    }
     406
     407    Pass3::Pass3( const Indexer *other_indexer )
     408        : Indexer( false ) {
     409        if ( other_indexer ) {
     410            indexer = other_indexer;
     411        } else {
     412            indexer = this;
     413        }
     414    }
     415
     416    void forallFixer( Type *func ) {
     417        // Fix up assertions
     418        for( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
     419            std::list< DeclarationWithType * > toBeDone, nextRound;
     420            toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
     421            while ( ! toBeDone.empty() ) {
     422                for( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
     423                    if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {
     424                        for( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
     425                            DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
     426                            assert( dwt );
     427                            nextRound.push_back( dwt->clone() );
     428                        }
     429                        delete ctx;
     430                    } else {
     431                        FixFunction fixer;
     432                        *assertion = (*assertion )->acceptMutator( fixer );
     433                        if ( fixer.get_isVoid() ) {
     434                            throw SemanticError( "invalid type void in assertion of function ", func );
     435                        }
     436                        (*type )->get_assertions().push_back( *assertion );
     437                    }
     438                }
     439                toBeDone.clear();
     440                toBeDone.splice( toBeDone.end(), nextRound );
     441            }
     442        }
     443    }
     444
     445    void Pass3::visit( ObjectDecl *object ) {
     446        forallFixer( object->get_type() );
     447        if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     448            forallFixer( pointer->get_base() );
     449        }
     450        Parent::visit( object );
     451        object->fixUniqueId();
     452    }
     453
     454    void Pass3::visit( FunctionDecl *func ) {
     455        forallFixer( func->get_type() );
     456        Parent::visit( func );
     457        func->fixUniqueId();
     458    }
     459
     460    static const std::list< std::string > noLabels;
     461
     462    void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) {
     463        AddStructAssignment visitor;
     464        acceptAndAdd( translationUnit, visitor, false );
     465    }
     466
     467    template< typename OutputIterator >
     468    void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
     469        ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); // PAB: unnamed bit fields are not copied
     470        if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
     471
     472        UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     473 
     474        UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     475        derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     476 
     477        // do something special for unnamed members
     478        Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
     479        assignExpr->get_args().push_back( dstselect );
     480 
     481        Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     482        assignExpr->get_args().push_back( srcselect );
     483 
     484        *out++ = new ExprStmt( noLabels, assignExpr );
     485    }
     486
     487    template< typename OutputIterator >
     488    void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
     489        static UniqueName indexName( "_index" );
     490 
     491        // for a flexible array member nothing is done -- user must define own assignment
     492        if ( ! array->get_dimension() ) return;
     493 
     494        ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
     495        *out++ = new DeclStmt( noLabels, index );
     496 
     497        UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
     498        init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     499        init->get_args().push_back( new NameExpr( "0" ) );
     500        Statement *initStmt = new ExprStmt( noLabels, init );
     501 
     502        UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
     503        cond->get_args().push_back( new VariableExpr( index ) );
     504        cond->get_args().push_back( array->get_dimension()->clone() );
     505 
     506        UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
     507        inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     508 
     509        UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     510 
     511        UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     512        derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     513 
     514        Expression *dstselect = new MemberExpr( member, derefExpr );
     515        UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
     516        dstIndex->get_args().push_back( dstselect );
     517        dstIndex->get_args().push_back( new VariableExpr( index ) );
     518        assignExpr->get_args().push_back( dstIndex );
     519 
     520        Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     521        UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     522        srcIndex->get_args().push_back( srcselect );
     523        srcIndex->get_args().push_back( new VariableExpr( index ) );
     524        assignExpr->get_args().push_back( srcIndex );
     525 
     526        *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
     527    }
     528
     529    Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType ) {
     530        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     531 
     532        ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     533        assignType->get_returnVals().push_back( returnVal );
     534 
     535        ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
     536        assignType->get_parameters().push_back( dstParam );
     537 
     538        ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
     539        assignType->get_parameters().push_back( srcParam );
     540 
     541        FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
     542        assignDecl->fixUniqueId();
     543 
     544        for( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
     545            if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
     546                if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
     547                    makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     548                } else {
     549                    makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
     550                }
     551            }
     552        }
     553        assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     554 
     555        return assignDecl;
     556    }
     557
     558    Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType ) {
     559        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     560 
     561        ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     562        assignType->get_returnVals().push_back( returnVal );
     563 
     564        ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
     565        assignType->get_parameters().push_back( dstParam );
     566 
     567        ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
     568        assignType->get_parameters().push_back( srcParam );
     569 
     570        FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
     571        assignDecl->fixUniqueId();
     572 
     573        UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
     574        copy->get_args().push_back( new VariableExpr( dstParam ) );
     575        copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
     576        copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
     577
     578        assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
     579        assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     580 
     581        return assignDecl;
     582    }
     583
     584    void AddStructAssignment::visit( StructDecl *structDecl ) {
     585        if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
     586            StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
     587            structInst->set_baseStruct( structDecl );
     588            declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
     589            structsDone.insert( structDecl->get_name() );
     590        }
     591    }
     592
     593    void AddStructAssignment::visit( UnionDecl *unionDecl ) {
     594        if ( ! unionDecl->get_members().empty() ) {
     595            UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
     596            unionInst->set_baseUnion( unionDecl );
     597            declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
     598        }
     599    }
     600
     601    void AddStructAssignment::visit( TypeDecl *typeDecl ) {
     602        CompoundStmt *stmts = 0;
     603        TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
     604        typeInst->set_baseType( typeDecl );
     605        ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
     606        ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
     607        if ( typeDecl->get_base() ) {
     608            stmts = new CompoundStmt( std::list< Label >() );
     609            UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     610            assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
     611            assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
     612            stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
     613        }
     614        FunctionType *type = new FunctionType( Type::Qualifiers(), false );
     615        type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
     616        type->get_parameters().push_back( dst );
     617        type->get_parameters().push_back( src );
     618        FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
     619        declsToAdd.push_back( func );
     620    }
     621
     622    void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
     623        if ( ! declsToAdd.empty() ) {
     624            for( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
     625                statements.insert( i, new DeclStmt( noLabels, *decl ) );
     626            }
     627            declsToAdd.clear();
     628        }
     629    }
     630
     631    void AddStructAssignment::visit( FunctionType *) {
     632        // ensure that we don't add assignment ops for types defined
     633        // as part of the function
     634    }
     635
     636    void AddStructAssignment::visit( PointerType *) {
     637        // ensure that we don't add assignment ops for types defined
     638        // as part of the pointer
     639    }
     640
     641    void AddStructAssignment::visit( ContextDecl *) {
     642        // ensure that we don't add assignment ops for types defined
     643        // as part of the context
     644    }
     645
     646    template< typename StmtClass >
     647    inline void AddStructAssignment::visitStatement( StmtClass *stmt ) {
     648        std::set< std::string > oldStructs = structsDone;
     649        addVisit( stmt, *this );
     650        structsDone = oldStructs;
     651    }
     652
     653    void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
     654        visitStatement( compoundStmt );
     655    }
     656
     657    void AddStructAssignment::visit( IfStmt *ifStmt ) {
     658        visitStatement( ifStmt );
     659    }
     660
     661    void AddStructAssignment::visit( WhileStmt *whileStmt ) {
     662        visitStatement( whileStmt );
     663    }
     664
     665    void AddStructAssignment::visit( ForStmt *forStmt ) {
     666        visitStatement( forStmt );
     667    }
     668
     669    void AddStructAssignment::visit( SwitchStmt *switchStmt ) {
     670        visitStatement( switchStmt );
     671    }
     672
     673    void AddStructAssignment::visit( ChooseStmt *switchStmt ) {
     674        visitStatement( switchStmt );
     675    }
     676
     677    void AddStructAssignment::visit( CaseStmt *caseStmt ) {
     678        visitStatement( caseStmt );
     679    }
     680
     681    void AddStructAssignment::visit( CatchStmt *cathStmt ) {
     682        visitStatement( cathStmt );
     683    }
     684
     685    bool isTypedef( Declaration *decl ) {
     686        return dynamic_cast< TypedefDecl * >( decl );
     687    }
     688
     689    void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
     690        EliminateTypedef eliminator;
     691        mutateAll( translationUnit, eliminator );
     692        filter( translationUnit, isTypedef, true );
     693    }
     694
     695    Type *EliminateTypedef::mutate( TypeInstType *typeInst ) {
     696        std::map< std::string, TypedefDecl * >::const_iterator def = typedefNames.find( typeInst->get_name() );
     697        if ( def != typedefNames.end() ) {
     698            Type *ret = def->second->get_base()->clone();
     699            ret->get_qualifiers() += typeInst->get_qualifiers();
     700            delete typeInst;
     701            return ret;
     702        }
     703        return typeInst;
     704    }
     705
     706    Declaration *EliminateTypedef::mutate( TypedefDecl *tyDecl ) {
     707        Declaration *ret = Mutator::mutate( tyDecl );
     708        typedefNames[ tyDecl->get_name() ] = tyDecl;
     709        if ( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl * >( tyDecl->get_base() ) ) {
     710            tyDecl->set_base( 0 );
     711            delete tyDecl;
     712            return aggDecl;
     713        } else {
     714            return ret;
     715        }
     716    }
     717
     718    TypeDecl *EliminateTypedef::mutate( TypeDecl *typeDecl ) {
     719        std::map< std::string, TypedefDecl * >::iterator i = typedefNames.find( typeDecl->get_name() );
     720        if ( i != typedefNames.end() ) {
     721            typedefNames.erase( i ) ;
     722        }
     723        return typeDecl;
     724    }
     725
     726    DeclarationWithType *EliminateTypedef::mutate( FunctionDecl *funcDecl ) {
     727        std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     728        DeclarationWithType *ret = Mutator::mutate( funcDecl );
     729        typedefNames = oldNames;
     730        return ret;
     731    }
     732
     733    ObjectDecl *EliminateTypedef::mutate( ObjectDecl *objDecl ) {
     734        std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     735        ObjectDecl *ret = Mutator::mutate( objDecl );
     736        typedefNames = oldNames;
     737        return ret;
     738    }
     739
     740    Expression *EliminateTypedef::mutate( CastExpr *castExpr ) {
     741        std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     742        Expression *ret = Mutator::mutate( castExpr );
     743        typedefNames = oldNames;
     744        return ret;
     745    }
     746
     747    CompoundStmt *EliminateTypedef::mutate( CompoundStmt *compoundStmt ) {
     748        std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     749        CompoundStmt *ret = Mutator::mutate( compoundStmt );
     750        std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
     751        while ( i != compoundStmt->get_kids().end() ) {
     752            std::list< Statement * >::iterator next = i;
     753            ++next;
     754            if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) {
     755                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
     756                    delete *i;
     757                    compoundStmt->get_kids().erase( i );
     758                }
     759            }
     760            i = next;
     761        }
     762        typedefNames = oldNames;
     763        return ret;
     764    }
    910765} // namespace SymTab
  • translator/SynTree/FunctionType.cc

    r8c17ab0 rc8ffe20b  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: FunctionType.cc,v 1.8 2005/08/29 20:59:25 rcbilson Exp $
    5  *
    6  */
    7 
    81#include <algorithm>
    92
     
    136
    147
    15 FunctionType::FunctionType( const Type::Qualifiers &tq, bool isVarArgs )
    16     : Type( tq ), isVarArgs( isVarArgs )
    17 {
     8FunctionType::FunctionType( const Type::Qualifiers &tq, bool isVarArgs ) : Type( tq ), isVarArgs( isVarArgs ) {
    189}
    1910
    20 FunctionType::FunctionType( const FunctionType &other )
    21     : Type( other ), isVarArgs( other.isVarArgs )
    22 {
     11FunctionType::FunctionType( const FunctionType &other ) : Type( other ), isVarArgs( other.isVarArgs ) {
    2312    cloneAll( other.returnVals, returnVals );
    2413    cloneAll( other.parameters, parameters );
    2514}
    2615
    27 FunctionType::~FunctionType()
    28 {
     16FunctionType::~FunctionType() {
    2917    deleteAll( returnVals );
    3018    deleteAll( parameters );
    3119}
    3220
    33 void
    34 FunctionType::print( std::ostream &os, int indent ) const
    35 {
     21void FunctionType::print( std::ostream &os, int indent ) const {
    3622    using std::string;
    3723    using std::endl;
     
    3925    Type::print( os, indent );
    4026    os << "function" << endl;
    41     if( !parameters.empty() ) {
    42         os << string( indent+2, ' ' ) << "with parameters" << endl;
    43         printAll( parameters, os, indent+4 );
    44         if( isVarArgs ) {
    45             os << string( indent+4, ' ' ) << "and a variable number of other arguments" << endl;
     27    if ( ! parameters.empty() ) {
     28        os << string( indent + 2, ' ' ) << "with parameters" << endl;
     29        printAll( parameters, os, indent + 4 );
     30        if ( isVarArgs ) {
     31            os << string( indent + 4, ' ' ) << "and a variable number of other arguments" << endl;
    4632        }
    47     } else if( isVarArgs ) {
    48         os << string( indent+4, ' ' ) << "accepting unspecified arguments" << endl;
     33    } else if ( isVarArgs ) {
     34        os << string( indent + 4, ' ' ) << "accepting unspecified arguments" << endl;
    4935    }
    50     os << string( indent+2, ' ' ) << "returning ";
    51     if( returnVals.empty() ) {
    52         os << endl << string( indent+4, ' ' ) << "nothing " << endl;
     36    os << string( indent + 2, ' ' ) << "returning ";
     37    if ( returnVals.empty() ) {
     38        os << endl << string( indent + 4, ' ' ) << "nothing " << endl;
    5339    } else {
    5440        os << endl;
    55         printAll( returnVals, os, indent+4 );
     41        printAll( returnVals, os, indent + 4 );
    5642    }
    57 
    5843}
    5944
  • translator/SynTree/Type.h

    r8c17ab0 rc8ffe20b  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: Type.h,v 1.30 2005/08/29 20:59:26 rcbilson Exp $
    5  *
    6  */
    7 
    81#ifndef TYPE_H
    92#define TYPE_H
     
    147
    158
    16 class Type
    17 {
    18 public:
    19     struct Qualifiers
    20     { 
    21         Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ) {}
    22         Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ) {}
     9class Type {
     10  public:
     11    struct Qualifiers { 
     12      Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ) {}
     13      Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ) {}
    2314       
    24         Qualifiers &operator+=( const Qualifiers &other);
    25         Qualifiers &operator-=( const Qualifiers &other);
     15        Qualifiers &operator+=( const Qualifiers &other );
     16        Qualifiers &operator-=( const Qualifiers &other );
    2617        Qualifiers operator+( const Type::Qualifiers &other );
    27         bool operator==( const Qualifiers &other);
    28         bool operator!=( const Qualifiers &other);
     18        bool operator==( const Qualifiers &other );
     19        bool operator!=( const Qualifiers &other );
    2920        bool operator<=( const Qualifiers &other );
    3021        bool operator>=( const Qualifiers &other );
     
    5748    virtual Type *acceptMutator( Mutator &m ) = 0;
    5849    virtual void print( std::ostream &os, int indent = 0 ) const;
    59 
    60 private:
     50  private:
    6151    Qualifiers tq;
    6252    std::list<TypeDecl*> forall;
    6353};
    6454
    65 class VoidType : public Type
    66 {
    67 public:
     55class VoidType : public Type {
     56  public:
    6857    VoidType( const Type::Qualifiers &tq );
    6958
     
    7463};
    7564
    76 class BasicType : public Type
    77 {
    78 public:
    79     enum Kind
    80         { 
    81             Bool,
    82             Char,
    83             SignedChar,
    84             UnsignedChar,
    85             ShortSignedInt,
    86             ShortUnsignedInt,
    87             SignedInt,
    88             UnsignedInt,
    89             LongSignedInt,
    90             LongUnsignedInt,
    91             LongLongSignedInt,
    92             LongLongUnsignedInt,
    93             Float,
    94             Double,
    95             LongDouble,
    96             FloatComplex,
    97             DoubleComplex,
    98             LongDoubleComplex,
    99             FloatImaginary,
    100             DoubleImaginary,
    101             LongDoubleImaginary,
    102             NUMBER_OF_BASIC_TYPES
    103         }; 
     65class BasicType : public Type {
     66  public:
     67    enum Kind { 
     68        Bool,
     69        Char,
     70        SignedChar,
     71        UnsignedChar,
     72        ShortSignedInt,
     73        ShortUnsignedInt,
     74        SignedInt,
     75        UnsignedInt,
     76        LongSignedInt,
     77        LongUnsignedInt,
     78        LongLongSignedInt,
     79        LongLongUnsignedInt,
     80        Float,
     81        Double,
     82        LongDouble,
     83        FloatComplex,
     84        DoubleComplex,
     85        LongDoubleComplex,
     86        FloatImaginary,
     87        DoubleImaginary,
     88        LongDoubleImaginary,
     89        NUMBER_OF_BASIC_TYPES
     90    }; 
    10491
    10592    BasicType( const Type::Qualifiers &tq, Kind bt );
     
    114101
    115102    bool isInteger() const;
    116 
    117 private:
     103  private:
    118104    Kind kind;
    119105};
    120106
    121 class PointerType : public Type
    122 {
    123 public:
     107class PointerType : public Type {
     108  public:
    124109    PointerType( const Type::Qualifiers &tq, Type *base );
    125110    PointerType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
     
    140125    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    141126    virtual void print( std::ostream &os, int indent = 0 ) const;
    142 
    143 private:
     127  private:
    144128    Type *base;
    145129   
    146     // in C99, pointer types can be qualified in many ways
    147     // e.g., int f( int a[ static 3 ] )
     130    // In C99, pointer types can be qualified in many ways e.g., int f( int a[ static 3 ] )
    148131    Expression *dimension;
    149132    bool isVarLen;
     
    151134};
    152135
    153 class ArrayType : public Type
    154 {
    155 public:
     136class ArrayType : public Type {
     137  public:
    156138    ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    157139    ArrayType( const ArrayType& );
     
    171153    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    172154    virtual void print( std::ostream &os, int indent = 0 ) const;
    173 
    174 private:
     155  private:
    175156    Type *base;
    176157    Expression *dimension;
     
    179160};
    180161
    181 class FunctionType : public Type
    182 {
    183 public:
     162class FunctionType : public Type {
     163  public:
    184164    FunctionType( const Type::Qualifiers &tq, bool isVarArgs );
    185165    FunctionType( const FunctionType& );
     
    195175    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    196176    virtual void print( std::ostream &os, int indent = 0 ) const;
    197 
    198 private:
     177  private:
    199178    std::list<DeclarationWithType*> returnVals;
    200179    std::list<DeclarationWithType*> parameters;
     
    207186};
    208187
    209 class ReferenceToType : public Type
    210 {
    211 public:
     188class ReferenceToType : public Type {
     189  public:
    212190    ReferenceToType( const Type::Qualifiers &tq, const std::string &name );
    213191    ReferenceToType( const ReferenceToType &other );
     
    222200    virtual Type *acceptMutator( Mutator &m ) = 0;
    223201    virtual void print( std::ostream &os, int indent = 0 ) const;
    224 
    225 protected:
     202  protected:
    226203    virtual std::string typeString() const = 0;
    227204    std::list< Expression* > parameters;
    228    
    229 private:
     205  private:
    230206    std::string name;
    231    
    232 };
    233 
    234 class StructInstType : public ReferenceToType
    235 {
     207};
     208
     209class StructInstType : public ReferenceToType {
    236210    typedef ReferenceToType Parent;
    237    
    238 public:
     211  public:
    239212    StructInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseStruct( 0 ) {}
    240213    StructInstType( const StructInstType &other ) : Parent( other ), baseStruct( other.baseStruct ) {}
     
    250223    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    251224
    252 private:
     225  private:
    253226    virtual std::string typeString() const;
    254227   
     
    258231};
    259232
    260 class UnionInstType : public ReferenceToType
    261 {
     233class UnionInstType : public ReferenceToType {
    262234    typedef ReferenceToType Parent;
    263    
    264 public:
     235  public:
    265236    UnionInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ), baseUnion( 0 ) {}
    266237    UnionInstType( const UnionInstType &other ) : Parent( other ), baseUnion( other.baseUnion ) {}
     
    275246    virtual void accept( Visitor &v ) { v.visit( this ); }
    276247    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    277 
    278 private:
     248  private:
    279249    virtual std::string typeString() const;
    280250   
     
    284254};
    285255
    286 class EnumInstType : public ReferenceToType
    287 {
     256class EnumInstType : public ReferenceToType {
    288257    typedef ReferenceToType Parent;
    289    
    290 public:
     258  public:
    291259    EnumInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ) {}
    292260    EnumInstType( const EnumInstType &other ) : Parent( other ) {}
     
    296264    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    297265
    298 private:
     266  private:
    299267    virtual std::string typeString() const;
    300268};
    301269
    302 class ContextInstType : public ReferenceToType
    303 {
     270class ContextInstType : public ReferenceToType {
    304271    typedef ReferenceToType Parent;
    305    
    306 public:
     272  public:
    307273    ContextInstType( const Type::Qualifiers &tq, const std::string &name ) : Parent( tq, name ) {}
    308274    ContextInstType( const ContextInstType &other );
     
    314280    virtual void accept( Visitor &v ) { v.visit( this ); }
    315281    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    316 
    317 private:
     282  private:
    318283    virtual std::string typeString() const;
    319284   
     
    323288};
    324289
    325 class TypeInstType : public ReferenceToType
    326 {
     290class TypeInstType : public ReferenceToType {
    327291    typedef ReferenceToType Parent;
    328    
    329 public:
     292  public:
    330293    TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType );
    331294    TypeInstType( const Type::Qualifiers &tq, const std::string &name, bool isFtype );
     
    341304    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    342305    virtual void print( std::ostream &os, int indent = 0 ) const;
    343 
    344 private:
     306  private:
    345307    virtual std::string typeString() const;
    346    
    347308    // this decl is not "owned" by the type inst; it is merely a pointer to elsewhere in the tree,
    348309    // where the type used here is actually defined
     
    351312};
    352313
    353 class TupleType : public Type
    354 {
    355 public:
     314class TupleType : public Type {
     315  public:
    356316    TupleType( const Type::Qualifiers &tq );
    357317    TupleType( const TupleType& );
     
    364324    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    365325    virtual void print( std::ostream &os, int indent = 0 ) const;
    366 
    367 private:
     326  private:
    368327    std::list<Type*> types;
    369328};
    370329
    371 class TypeofType : public Type
    372 {
    373 public:
     330class TypeofType : public Type {
     331  public:
    374332    TypeofType( const Type::Qualifiers &tq, Expression *expr );
    375333    TypeofType( const TypeofType& );
     
    383341    virtual Type *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    384342    virtual void print( std::ostream &os, int indent = 0 ) const;
    385 
    386 private:
     343  private:
    387344    Expression *expr;
    388345};
    389346
    390 class AttrType : public Type
    391 {
    392 public:
     347class AttrType : public Type {
     348  public:
    393349    AttrType( const Type::Qualifiers &tq, const std::string &name, Expression *expr );
    394350    AttrType( const Type::Qualifiers &tq, const std::string &name, Type *type );
     
    410366    virtual void print( std::ostream &os, int indent = 0 ) const;
    411367
    412 private:
     368  private:
    413369    std::string name;
    414370    Expression *expr;
     
    417373};
    418374
    419 inline Type::Qualifiers &
    420 Type::Qualifiers::operator+=( const Type::Qualifiers &other )
    421 {
     375inline Type::Qualifiers &Type::Qualifiers::operator+=( const Type::Qualifiers &other ) {
    422376    isConst |= other.isConst;
    423377    isVolatile |= other.isVolatile;
     
    427381}
    428382
    429 inline Type::Qualifiers &
    430 Type::Qualifiers::operator-=( const Type::Qualifiers &other )
    431 {
    432     if( other.isConst ) isConst = 0;
    433     if( other.isVolatile ) isVolatile = 0;
    434     if( other.isRestrict ) isRestrict = 0;
     383inline Type::Qualifiers &Type::Qualifiers::operator-=( const Type::Qualifiers &other ) {
     384    if ( other.isConst ) isConst = 0;
     385    if ( other.isVolatile ) isVolatile = 0;
     386    if ( other.isRestrict ) isRestrict = 0;
    435387    return *this;
    436388}
    437389
    438 inline Type::Qualifiers
    439 Type::Qualifiers::operator+( const Type::Qualifiers &other )
    440 {
     390inline Type::Qualifiers Type::Qualifiers::operator+( const Type::Qualifiers &other ) {
    441391    Qualifiers q = other;
    442392    q += *this;
     
    444394}
    445395
    446 inline bool
    447 Type::Qualifiers::operator==( const Qualifiers &other)
    448 {
     396inline bool Type::Qualifiers::operator==( const Qualifiers &other ) {
    449397    return isConst == other.isConst
    450         && isVolatile == other.isVolatile
    451         && isRestrict == other.isRestrict;
     398    && isVolatile == other.isVolatile
     399    && isRestrict == other.isRestrict;
    452400///         && isLvalue == other.isLvalue;
    453401}
    454402
    455 inline bool
    456 Type::Qualifiers::operator!=( const Qualifiers &other)
    457 {
     403inline bool Type::Qualifiers::operator!=( const Qualifiers &other ) {
    458404    return isConst != other.isConst
    459405        || isVolatile != other.isVolatile
     
    462408}
    463409
    464 inline bool
    465 Type::Qualifiers::operator<=( const Type::Qualifiers &other )
    466 {
     410inline bool Type::Qualifiers::operator<=( const Type::Qualifiers &other ) {
    467411    return isConst <= other.isConst
    468412        && isVolatile <= other.isVolatile
     
    471415}
    472416
    473 inline bool
    474 Type::Qualifiers::operator>=( const Type::Qualifiers &other )
    475 {
     417inline bool Type::Qualifiers::operator>=( const Type::Qualifiers &other ) {
    476418    return isConst >= other.isConst
    477419        && isVolatile >= other.isVolatile
     
    480422}
    481423
    482 inline bool
    483 Type::Qualifiers::operator<( const Type::Qualifiers &other )
    484 {
     424inline bool Type::Qualifiers::operator<( const Type::Qualifiers &other ) {
    485425    return operator!=( other ) && operator<=( other );
    486426}
    487427
    488 inline bool
    489 Type::Qualifiers::operator>( const Type::Qualifiers &other )
    490 {
     428inline bool Type::Qualifiers::operator>( const Type::Qualifiers &other ) {
    491429    return operator!=( other ) && operator>=( other );
    492430}
    493431
    494 
    495 #endif /* #ifndef TYPE_H */
     432#endif // TYPE_H
Note: See TracChangeset for help on using the changeset viewer.