source: src/Parser/DeclarationNode.cc @ 2794fff

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 2794fff was 71bd8c6, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

fix isVarLen in array types, fix loss of typedef when variable of aggregate type is declared, fix duplicate typedef with arrays of constant size

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