source: translator/Parser/DeclarationNode.cc @ bdd516a

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since bdd516a was bdd516a, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

fixed sizeof type variable, find lowest cost alternative for sizeof expression, removed unused classes, added compiler flag, remove temporary file for -CFA, formatting

  • Property mode set to 100644
File size: 27.5 KB
Line 
1#include <string>
2#include <list>
3#include <iterator>
4#include <algorithm>
5#include <cassert>
6
7#include "TypeData.h"
8#include "SynTree/Expression.h"
9
10
11using namespace std;
12
13// These must remain in the same order as the corresponding DeclarationNode enumerations.
14const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic" };
15const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "_Bool", "_Complex", "_Imaginary" };
16const char *DeclarationNode::modifierName[] = { "signed", "unsigned", "short", "long" };
17const char *DeclarationNode::tyConName[] = { "struct", "union", "context" };
18const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" };
19
20UniqueName DeclarationNode::anonymous( "__anonymous" );
21
22extern LinkageSpec::Type linkage;               /* defined in cfa.y */
23
24DeclarationNode *DeclarationNode::clone() const {
25    DeclarationNode *newnode = new DeclarationNode;
26    newnode->type = maybeClone( type );
27    newnode->name = name;
28    newnode->storageClasses = storageClasses;
29    newnode->bitfieldWidth = maybeClone( bitfieldWidth );
30    newnode->hasEllipsis = hasEllipsis;
31    newnode->initializer = initializer;
32    newnode->next = maybeClone( next );
33    newnode->linkage = linkage;
34    return newnode;
35}
36
37DeclarationNode::DeclarationNode() : type( 0 ), bitfieldWidth( 0 ), initializer( 0 ), hasEllipsis( false ), linkage( ::linkage ) {
38}
39
40DeclarationNode::~DeclarationNode() {
41    delete type;
42    delete bitfieldWidth;
43    delete initializer;
44}
45
46bool DeclarationNode::get_hasEllipsis() const {
47    return hasEllipsis;
48}
49
50const char *storageClassName[] = {
51    // order must correspond with DeclarationNode::StorageClass
52    "static",
53    "auto",
54    "extern",
55    "register",
56    "inline",
57    "fortran",
58};
59
60void DeclarationNode::print( std::ostream &os, int indent ) const {
61    os << string(indent, ' ' );
62    if ( name == "" ) {
63        os << "unnamed: ";
64    } else {
65        os << name << ": ";
66    }
67
68    if ( linkage != LinkageSpec::Cforall ) {
69        os << LinkageSpec::toString( linkage ) << " ";
70    }
71
72    printEnums( storageClasses.begin(), storageClasses.end(), storageClassName, os );
73    if ( type ) {
74        type->print( os, indent );
75    } else {
76        os << "untyped entity ";
77    }
78
79    if ( bitfieldWidth ) {
80        os << endl << string(indent+2,  ' ') << "with bitfield width ";
81        bitfieldWidth->printOneLine( os );
82    }
83
84    if ( initializer != 0 ) {
85        os << endl << string(indent+2,  ' ') << "with initializer ";
86        initializer->printOneLine( os );
87    }
88
89    os << endl;
90}
91
92void DeclarationNode::printList( std::ostream &os, int indent ) const {
93    ParseNode::printList( os, indent );
94    if ( hasEllipsis ) {
95        os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
96    }
97}
98
99DeclarationNode *DeclarationNode::newFunction( std::string *name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) {
100    DeclarationNode *newnode = new DeclarationNode;
101    newnode->name = assign_strptr( name );
102
103    newnode->type = new TypeData( TypeData::Function );
104    newnode->type->function->params = param;
105    newnode->type->function->newStyle = newStyle;
106    newnode->type->function->body = body;
107
108    if ( body ) {
109        newnode->type->function->hasBody = true;
110    }
111
112    if ( ret ) {
113        newnode->type->base = ret->type;
114        ret->type = 0;
115        delete ret;
116    }
117
118    return newnode;
119}
120
121DeclarationNode *DeclarationNode::newQualifier( Qualifier q ) {
122    DeclarationNode *newnode = new DeclarationNode;
123    newnode->type = new TypeData();
124    newnode->type->qualifiers.push_back( q );
125    return newnode;
126}
127
128DeclarationNode *DeclarationNode::newStorageClass( StorageClass sc ) {
129    DeclarationNode *newnode = new DeclarationNode;
130    newnode->storageClasses.push_back( sc );
131    return newnode;
132}
133
134DeclarationNode *DeclarationNode::newBasicType( BasicType bt ) {
135    DeclarationNode *newnode = new DeclarationNode;
136    newnode->type = new TypeData( TypeData::Basic );
137    newnode->type->basic->typeSpec.push_back( bt );
138    return newnode;
139}
140
141DeclarationNode *DeclarationNode::newModifier( Modifier mod ) {
142    DeclarationNode *newnode = new DeclarationNode;
143    newnode->type = new TypeData( TypeData::Basic );
144    newnode->type->basic->modifiers.push_back( mod );
145    return newnode;
146}
147
148DeclarationNode *DeclarationNode::newForall( DeclarationNode* forall ) {
149    DeclarationNode *newnode = new DeclarationNode;
150    newnode->type = new TypeData( TypeData::Unknown );
151    newnode->type->forall = forall;
152    return newnode;
153}
154
155DeclarationNode *DeclarationNode::newFromTypedef( std::string* name ) {
156    DeclarationNode *newnode = new DeclarationNode;
157    newnode->type = new TypeData( TypeData::SymbolicInst );
158    newnode->type->symbolic->name = assign_strptr( name );
159    newnode->type->symbolic->isTypedef = true;
160    newnode->type->symbolic->params = 0;
161    return newnode;
162}
163
164DeclarationNode *DeclarationNode::newAggregate( TyCon kind, std::string* name, DeclarationNode *formals, ExpressionNode *actuals, DeclarationNode *fields ) {
165    DeclarationNode *newnode = new DeclarationNode;
166    newnode->type = new TypeData( TypeData::Aggregate );
167    newnode->type->aggregate->kind = kind;
168    newnode->type->aggregate->name = assign_strptr( name );
169    if ( newnode->type->aggregate->name == "" ) {
170        newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
171    }
172    newnode->type->aggregate->params = formals;
173    newnode->type->aggregate->actuals = actuals;
174    newnode->type->aggregate->members = fields;
175    return newnode;
176}
177
178DeclarationNode *DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) {
179    DeclarationNode *newnode = new DeclarationNode;
180    newnode->name = assign_strptr( name );
181    newnode->type = new TypeData( TypeData::Enum );
182    newnode->type->enumeration->name = newnode->name;
183    if ( newnode->type->enumeration->name == "" ) {
184        newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
185    }
186    newnode->type->enumeration->constants = constants;
187    return newnode;
188}
189
190DeclarationNode *DeclarationNode::newEnumConstant( std::string* name, ExpressionNode *constant ) {
191    DeclarationNode *newnode = new DeclarationNode;
192    newnode->name = assign_strptr( name );
193    // do something with the constant
194    return newnode;
195}
196
197DeclarationNode *DeclarationNode::newName( std::string* name ) {
198    DeclarationNode *newnode = new DeclarationNode;
199    newnode->name = assign_strptr( name );
200    return newnode;
201}
202
203DeclarationNode *DeclarationNode::newFromTypeGen( std::string* name, ExpressionNode *params ) {
204    DeclarationNode *newnode = new DeclarationNode;
205    newnode->type = new TypeData( TypeData::SymbolicInst );
206    newnode->type->symbolic->name = assign_strptr( name );
207    newnode->type->symbolic->isTypedef = false;
208    newnode->type->symbolic->actuals = params;
209    return newnode;
210}
211
212DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string* name ) {
213    DeclarationNode *newnode = new DeclarationNode;
214    newnode->name = assign_strptr( name );
215    newnode->type = new TypeData( TypeData::Variable );
216    newnode->type->variable->tyClass = tc;
217    newnode->type->variable->name = newnode->name;
218    return newnode;
219}
220
221DeclarationNode *DeclarationNode::newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) {
222    DeclarationNode *newnode = new DeclarationNode;
223    newnode->type = new TypeData( TypeData::Aggregate );
224    newnode->type->aggregate->kind = Context;
225    newnode->type->aggregate->params = params;
226    newnode->type->aggregate->members = asserts;
227    newnode->type->aggregate->name = assign_strptr( name );
228    return newnode;
229}
230
231DeclarationNode *DeclarationNode::newContextUse( std::string *name, ExpressionNode *params ) {
232    DeclarationNode *newnode = new DeclarationNode;
233    newnode->type = new TypeData( TypeData::AggregateInst );
234    newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
235    newnode->type->aggInst->aggregate->aggregate->kind = Context;
236    newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name );
237    newnode->type->aggInst->params = params;
238    return newnode;
239}
240
241DeclarationNode *DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) {
242    DeclarationNode *newnode = new DeclarationNode;
243    newnode->name = assign_strptr( name );
244    newnode->type = new TypeData( TypeData::Symbolic );
245    newnode->type->symbolic->isTypedef = false;
246    newnode->type->symbolic->params = typeParams;
247    newnode->type->symbolic->name = newnode->name;
248    return newnode;
249}
250
251DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) {
252    DeclarationNode *newnode = new DeclarationNode;
253    newnode->type = new TypeData( TypeData::Pointer );
254    return newnode->addQualifiers( qualifiers );
255}
256
257DeclarationNode *DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) {
258    DeclarationNode *newnode = new DeclarationNode;
259    newnode->type = new TypeData( TypeData::Array );
260    newnode->type->array->dimension = size;
261    newnode->type->array->isStatic = isStatic;
262    newnode->type->array->isVarLen = false;
263    return newnode->addQualifiers( qualifiers );
264}
265
266DeclarationNode *DeclarationNode::newVarArray( DeclarationNode *qualifiers ) {
267    DeclarationNode *newnode = new DeclarationNode;
268    newnode->type = new TypeData( TypeData::Array );
269    newnode->type->array->dimension = 0;
270    newnode->type->array->isStatic = false;
271    newnode->type->array->isVarLen = true;
272    return newnode->addQualifiers( qualifiers );
273}
274
275DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) {
276    DeclarationNode *newnode = new DeclarationNode;
277    newnode->bitfieldWidth = size;
278    return newnode;
279}
280
281DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) {
282    DeclarationNode *newnode = new DeclarationNode;
283    newnode->type = new TypeData( TypeData::Tuple );
284    newnode->type->tuple->members = members;
285    return newnode;
286}
287
288DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) {
289    DeclarationNode *newnode = new DeclarationNode;
290    newnode->type = new TypeData( TypeData::Typeof );
291    newnode->type->typeexpr->expr = expr;
292    return newnode;
293}
294
295DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) {
296    DeclarationNode *newnode = new DeclarationNode;
297    newnode->type = new TypeData( TypeData::Attr );
298    newnode->type->attr->name = assign_strptr( name );
299    newnode->type->attr->expr = expr;
300    return newnode;
301}
302
303DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) {
304    DeclarationNode *newnode = new DeclarationNode;
305    newnode->type = new TypeData( TypeData::Attr );
306    newnode->type->attr->name = assign_strptr( name );
307    newnode->type->attr->type = type;
308    return newnode;
309}
310
311static void addQualifiersToType( TypeData *&src, TypeData *dst ) {
312    if ( src && dst ) {
313        if ( src->forall && dst->kind == TypeData::Function ) {
314            if ( dst->forall ) {
315                dst->forall->appendList( src->forall );
316            } else {
317                dst->forall = src->forall;
318            }
319            src->forall = 0;
320        }
321        if ( dst->base ) {
322            addQualifiersToType( src, dst->base );
323        } else if ( dst->kind == TypeData::Function ) {
324            dst->base = src;
325            src = 0;
326        } else {
327            dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
328        }
329    }
330}
331     
332DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
333    if ( q ) {
334        storageClasses.splice( storageClasses.end(), q->storageClasses );
335        if ( q->type ) {
336            if ( ! type ) {
337                type = new TypeData;
338            }
339            addQualifiersToType( q->type, type );
340            if ( q->type && q->type->forall ) {
341                if ( type->forall ) {
342                    type->forall->appendList( q->type->forall );
343                } else {
344                    type->forall = q->type->forall;
345                }
346                q->type->forall = 0;
347            }
348        }
349    }
350    delete q;
351    return this;
352}
353
354DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
355    storageClasses = q->storageClasses;
356    return this;
357}
358
359static void addTypeToType( TypeData *&src, TypeData *&dst ) {
360    if ( src && dst ) {
361        if ( src->forall && dst->kind == TypeData::Function ) {
362            if ( dst->forall ) {
363                dst->forall->appendList( src->forall );
364            } else {
365                dst->forall = src->forall;
366            }
367            src->forall = 0;
368        }
369        if ( dst->base ) {
370            addTypeToType( src, dst->base );
371        } else {
372            switch ( dst->kind ) {
373              case TypeData::Unknown:
374                src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
375                dst = src;
376                src = 0;
377                break;
378
379              case TypeData::Basic:
380                dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
381                if ( src->kind != TypeData::Unknown ) {
382                    assert( src->kind == TypeData::Basic );
383                    dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
384                    dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
385                }
386                break;
387
388              default:
389                switch ( src->kind ) {
390                  case TypeData::Aggregate:
391                  case TypeData::Enum:
392                    dst->base = new TypeData( TypeData::AggregateInst );
393                    dst->base->aggInst->aggregate = src;
394                    if ( src->kind == TypeData::Aggregate ) {
395                        dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
396                    }
397                    dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
398                    src = 0;
399                    break;
400         
401                  default:
402                    if ( dst->forall ) {
403                        dst->forall->appendList( src->forall );
404                    } else {
405                        dst->forall = src->forall;
406                    }
407                    src->forall = 0;
408                    dst->base = src;
409                    src = 0;
410                }
411            }
412        }
413    }
414}
415
416DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
417    if ( o ) {
418        storageClasses.splice( storageClasses.end(), o->storageClasses );
419        if ( o->type ) {
420            if ( ! type ) {
421                if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
422                    type = new TypeData( TypeData::AggregateInst );
423                    type->aggInst->aggregate = o->type;
424                    if ( o->type->kind == TypeData::Aggregate ) {
425                        type->aggInst->params = maybeClone( o->type->aggregate->actuals );
426                    }
427                    type->qualifiers.splice( type->qualifiers.end(), o->type->qualifiers );
428                } else {
429                    type = o->type;
430                }
431                o->type = 0;
432            } else {
433                addTypeToType( o->type, type );
434            }
435        }
436        if ( o->bitfieldWidth ) {
437            bitfieldWidth = o->bitfieldWidth;
438        }
439    }
440    delete o;
441    return this;
442}
443
444DeclarationNode *DeclarationNode::addTypedef() {
445    TypeData *newtype = new TypeData( TypeData::Symbolic );
446    newtype->symbolic->params = 0;
447    newtype->symbolic->isTypedef = true;
448    newtype->symbolic->name = name;
449    newtype->base = type;
450    type = newtype;
451    return this;
452}
453
454DeclarationNode *DeclarationNode::addAssertions( DeclarationNode* assertions ) {
455    assert( type );
456    switch ( type->kind ) {
457      case TypeData::Symbolic:
458        if ( type->symbolic->assertions ) {
459            type->symbolic->assertions->appendList( assertions );
460        } else {
461            type->symbolic->assertions = assertions;
462        }
463        break;
464   
465      case TypeData::Variable:
466        if ( type->variable->assertions ) {
467            type->variable->assertions->appendList( assertions );
468        } else {
469            type->variable->assertions = assertions;
470        }
471        break;
472   
473      default:
474        assert( false );
475    }
476   
477    return this;
478}
479
480DeclarationNode *DeclarationNode::addName( std::string* newname ) {
481    name = assign_strptr( newname );
482    return this;
483}
484
485DeclarationNode *DeclarationNode::addBitfield( ExpressionNode *size ) {
486    bitfieldWidth = size;
487    return this;
488}
489
490DeclarationNode *DeclarationNode::addVarArgs() {
491    assert( type );
492    hasEllipsis = true;
493    return this;
494}
495
496DeclarationNode *DeclarationNode::addFunctionBody( StatementNode *body ) {
497    assert( type );
498    assert( type->kind == TypeData::Function );
499    assert( type->function->body == 0 );
500    type->function->body = body;
501    type->function->hasBody = true;
502    return this;
503}
504
505DeclarationNode *DeclarationNode::addOldDeclList( DeclarationNode *list ) {
506    assert( type );
507    assert( type->kind == TypeData::Function );
508    assert( type->function->oldDeclList == 0 );
509    type->function->oldDeclList = list;
510    return this;
511}
512
513static void
514setBase( TypeData *&type, TypeData *newType ) {
515    if ( type ) {
516        TypeData *prevBase = type;
517        TypeData *curBase = type->base;
518        while( curBase != 0 ) {
519            prevBase = curBase;
520            curBase = curBase->base;
521        }
522        prevBase->base = newType;
523    } else {
524        type = newType;
525    }
526}
527
528DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) {
529    if ( p ) {
530        assert( p->type->kind == TypeData::Pointer );
531        setBase( type, p->type );
532        p->type = 0;
533        delete p;
534    }
535    return this;
536}
537
538DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) {
539    if ( a ) {
540        assert( a->type->kind == TypeData::Array );
541        setBase( type, a->type );
542        a->type = 0;
543        delete a;
544    }
545    return this;
546}
547
548DeclarationNode *DeclarationNode::addNewPointer( DeclarationNode *p ) {
549    if ( p ) {
550        assert( p->type->kind == TypeData::Pointer );
551        if ( type ) {
552            switch ( type->kind ) {
553              case TypeData::Aggregate:
554              case TypeData::Enum:
555                p->type->base = new TypeData( TypeData::AggregateInst );
556                p->type->base->aggInst->aggregate = type;
557                if ( type->kind == TypeData::Aggregate ) {
558                    p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
559                }
560                p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
561                break;
562       
563              default:
564                p->type->base = type;
565            }
566            type = 0;
567        }
568        delete this;
569        return p;
570    } else {
571        return this;
572    }
573}
574
575static TypeData *findLast( TypeData *a ) {
576    assert( a );
577    TypeData *cur = a;
578    while( cur->base ) {
579        cur = cur->base;
580    }
581    return cur;
582}
583
584DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
585    if ( a ) {
586        assert( a->type->kind == TypeData::Array );
587        TypeData *lastArray = findLast( a->type );
588        if ( type ) { 
589            switch ( type->kind ) {
590              case TypeData::Aggregate:
591              case TypeData::Enum:
592                lastArray->base = new TypeData( TypeData::AggregateInst );
593                lastArray->base->aggInst->aggregate = type;
594                if ( type->kind == TypeData::Aggregate ) {
595                    lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
596                }
597                lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
598                break;
599       
600              default:
601                lastArray->base = type;
602            }
603            type = 0;
604        }
605        delete this;
606        return a;
607    } else {
608        return this;
609    }
610}
611
612DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
613    TypeData *ftype = new TypeData( TypeData::Function );
614    ftype->function->params = params;
615    setBase( type, ftype );
616    return this;
617}
618
619static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
620    if ( type ) {
621        if ( type->kind != TypeData::Function ) {
622            type->base = addIdListToType( type->base, ids );
623        } else {
624            type->function->idList = ids;
625        }
626        return type;
627    } else {
628        TypeData *newtype = new TypeData( TypeData::Function );
629        newtype->function->idList = ids;
630        return newtype;
631    }
632}
633   
634DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
635    type = addIdListToType( type, ids );
636    return this;
637}
638
639DeclarationNode *DeclarationNode::addInitializer( InitializerNode *init ) {
640    //assert
641    initializer = init;
642    return this;
643}
644
645DeclarationNode *DeclarationNode::cloneBaseType( string *newName ) {
646    DeclarationNode *newnode = new DeclarationNode;
647    TypeData *srcType = type;
648    while( srcType->base ) {
649        srcType = srcType->base;
650    }
651    newnode->type = maybeClone( srcType );
652    if ( newnode->type->kind == TypeData::AggregateInst ) {
653        // don't duplicate members
654        if ( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
655            delete newnode->type->aggInst->aggregate->enumeration->constants;
656            newnode->type->aggInst->aggregate->enumeration->constants = 0;
657        } else {
658            assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
659            delete newnode->type->aggInst->aggregate->aggregate->members;
660            newnode->type->aggInst->aggregate->aggregate->members = 0;
661        }
662    }
663    newnode->type->forall = maybeClone( type->forall );
664    newnode->storageClasses = storageClasses;
665    newnode->name = assign_strptr( newName );
666    return newnode;
667}
668
669DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
670    if ( o ) {
671        o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
672        if ( type ) {
673            TypeData *srcType = type;
674            while( srcType->base ) {
675                srcType = srcType->base;
676            }
677            TypeData *newType = srcType->clone();
678            if ( newType->kind == TypeData::AggregateInst ) {
679                // don't duplicate members
680                if ( newType->aggInst->aggregate->kind == TypeData::Enum ) {
681                    delete newType->aggInst->aggregate->enumeration->constants;
682                    newType->aggInst->aggregate->enumeration->constants = 0;
683                } else {
684                    assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
685                    delete newType->aggInst->aggregate->aggregate->members;
686                    newType->aggInst->aggregate->aggregate->members = 0;
687                }
688            }
689            newType->forall = maybeClone( type->forall );
690            if ( ! o->type ) {
691                o->type = newType;
692            } else {
693                addTypeToType( newType, o->type );
694                delete newType;
695            }
696        }
697    }
698    return o;
699}
700
701DeclarationNode *DeclarationNode::cloneType( string *newName ) {
702    DeclarationNode *newnode = new DeclarationNode;
703    newnode->type = maybeClone( type );
704    newnode->storageClasses = storageClasses;
705    newnode->name = assign_strptr( newName );
706    return newnode;
707}
708
709DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
710    if ( o ) {
711        o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
712        if ( type ) {
713            TypeData *newType = type->clone();
714            if ( ! o->type ) {
715                o->type = newType;
716            } else {
717                addTypeToType( newType, o->type );
718                delete newType;
719            }
720        }
721    }
722    return o;
723}
724
725DeclarationNode *DeclarationNode::appendList( DeclarationNode *node ) {
726    if ( node != 0 ) {
727        set_link( node );
728    }
729    return this;
730}
731
732DeclarationNode *DeclarationNode::extractAggregate() const {
733    if ( type ) {
734        TypeData *ret = type->extractAggregate();
735        if ( ret ) {
736            DeclarationNode *newnode = new DeclarationNode;
737            newnode->type = ret;
738            return newnode;
739        } else {
740            return 0;
741        }
742    } else {
743        return 0;
744    }
745}
746
747void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList ) {
748    SemanticError errors;
749    std::back_insert_iterator< std::list< Declaration* > > out( outputList );
750    const DeclarationNode *cur = firstNode;
751    while( cur ) {
752        try {
753            if ( DeclarationNode *extr = cur->extractAggregate() ) {
754                // handle the case where a structure declaration is contained within an object or type
755                // declaration
756                Declaration *decl = extr->build();
757                if ( decl ) {
758                   *out++ = decl;
759                }
760            }
761            Declaration *decl = cur->build();
762            if ( decl ) {
763                *out++ = decl;
764            }
765        } catch( SemanticError &e ) {
766            errors.append( e );
767        }
768        cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
769    }
770    if ( ! errors.isEmpty() ) {
771        throw errors;
772    }
773}
774
775void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList ) {
776    SemanticError errors;
777    std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
778    const DeclarationNode *cur = firstNode;
779    while( cur ) {
780        try {
781///       if ( DeclarationNode *extr = cur->extractAggregate() ) {
782///     // handle the case where a structure declaration is contained within an object or type
783///     // declaration
784///     Declaration *decl = extr->build();
785///     if ( decl ) {
786///          *out++ = decl;
787///     }
788///       }
789            Declaration *decl = cur->build();
790            if ( decl ) {
791                if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
792                   *out++ = dwt;
793                } else if ( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
794                    StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
795                    *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
796                    delete agg;
797                } else if ( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
798                    UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
799                    *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
800                }
801            }
802        } catch( SemanticError &e ) {
803            errors.append( e );
804        }
805        cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
806    }
807    if ( ! errors.isEmpty() ) {
808        throw errors;
809    }
810}
811
812void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList ) {
813    SemanticError errors;
814    std::back_insert_iterator< std::list< Type* > > out( outputList );
815    const DeclarationNode *cur = firstNode;
816    while( cur ) {
817        try {
818           *out++ = cur->buildType();
819        } catch( SemanticError &e ) {
820            errors.append( e );
821        }
822        cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
823    }
824    if ( ! errors.isEmpty() ) {
825        throw errors;
826    }
827}
828
829Declaration *DeclarationNode::build() const {
830
831    if ( ! type ) {
832        if ( buildInline() ) {
833            throw SemanticError( "invalid inline specification in declaration of ", this );
834        } else {
835            return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
836        }
837    } else {
838        Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
839        return newDecl;
840    }
841    // we should never get here
842    assert( false );
843    return 0;
844}
845
846Type *DeclarationNode::buildType() const {
847    assert( type );
848 
849    switch ( type->kind ) {
850      case TypeData::Enum:
851        return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
852      case TypeData::Aggregate: {
853          ReferenceToType *ret;
854          switch ( type->aggregate->kind ) {
855            case DeclarationNode::Struct:
856              ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
857              break;
858            case DeclarationNode::Union:
859              ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
860              break;
861            case DeclarationNode::Context:
862              ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
863              break;
864            default:
865              assert( false );
866          } // switch
867          buildList( type->aggregate->actuals, ret->get_parameters() );
868          return ret;
869      }
870      case TypeData::Symbolic: {
871          TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
872          buildList( type->symbolic->actuals, ret->get_parameters() );
873          return ret;
874      }
875      default:
876        return type->build();
877    } // switch
878}
879
880Declaration::StorageClass DeclarationNode::buildStorageClass() const {
881    static const Declaration::StorageClass scMap[] = { 
882        Declaration::Static,
883        Declaration::Auto,
884        Declaration::Extern,
885        Declaration::Register,
886        Declaration::NoStorageClass, // inline
887        Declaration::Fortran
888    }; 
889 
890    Declaration::StorageClass ret = Declaration::NoStorageClass;
891    for ( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
892        assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
893        if ( *i == Inline ) continue;
894        if ( ret == Declaration::NoStorageClass ) {
895            ret = scMap[ *i ];
896        } else {
897            throw SemanticError( "invalid combination of storage classes in declaration of ", this );
898        }
899    }
900    return ret;
901}
902
903bool DeclarationNode::buildInline() const {
904    std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
905    if ( first == storageClasses.end() ) {
906        return false;
907    } else {
908        std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
909        if ( next == storageClasses.end() ) {
910            return true;
911        } else {
912            throw SemanticError( "duplicate inline specification in declaration of ", this );
913        }
914    }
915    // we should never get here
916    return false;
917}
Note: See TracBrowser for help on using the repository browser.