source: src/Parser/DeclarationNode.cc @ 1869adf

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 1869adf was de62360d, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

fix computed goto, fixed -std=, implicit typedefs for enum and aggregates, add _Noreturn _Thread_local

  • Property mode set to 100644
File size: 28.5 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 : Peter A. Buhr
12// Last Modified On : Wed Jun 24 15:29:19 2015
13// Update Count     : 86
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, std::string *name, DeclarationNode *formals, 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 == "" ) {
181                newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
182        } // if
183
184        // SKULLDUGGERY: generate a typedef for the aggregate name so that the aggregate does not have to be qualified by
185        // "struct"
186        typedefTable.addToEnclosingScope( newnode->type->aggregate->name, TypedefTable::TD );
187        DeclarationNode *typedf = new DeclarationNode;
188        typedf->name = newnode->type->aggregate->name;
189        newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );
190
191        newnode->type->aggregate->params = formals;
192        newnode->type->aggregate->actuals = actuals;
193        newnode->type->aggregate->members = fields;
194        return newnode;
195}
196
197DeclarationNode *DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) {
198        DeclarationNode *newnode = new DeclarationNode;
199        newnode->name = assign_strptr( name );
200        newnode->type = new TypeData( TypeData::Enum );
201        newnode->type->enumeration->name = newnode->name;
202        if ( newnode->type->enumeration->name == "" ) {
203                newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
204        } // if
205
206        // SKULLDUGGERY: generate a typedef for the enumeration name so that the enumeration does not have to be qualified
207        // by "enum"
208        typedefTable.addToEnclosingScope( newnode->type->enumeration->name, TypedefTable::TD );
209        DeclarationNode *typedf = new DeclarationNode;
210        typedf->name = newnode->type->enumeration->name;
211        newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );
212
213        newnode->type->enumeration->constants = constants;
214        return newnode;
215}
216
217DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) {
218        DeclarationNode *newnode = new DeclarationNode;
219        newnode->name = assign_strptr( name );
220        // do something with the constant
221        return newnode;
222}
223
224DeclarationNode *DeclarationNode::newName( std::string *name ) {
225        DeclarationNode *newnode = new DeclarationNode;
226        newnode->name = assign_strptr( name );
227        return newnode;
228}
229
230DeclarationNode *DeclarationNode::newFromTypeGen( std::string *name, ExpressionNode *params ) {
231        DeclarationNode *newnode = new DeclarationNode;
232        newnode->type = new TypeData( TypeData::SymbolicInst );
233        newnode->type->symbolic->name = assign_strptr( name );
234        newnode->type->symbolic->isTypedef = false;
235        newnode->type->symbolic->actuals = params;
236        return newnode;
237}
238
239DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string *name ) {
240        DeclarationNode *newnode = new DeclarationNode;
241        newnode->name = assign_strptr( name );
242        newnode->type = new TypeData( TypeData::Variable );
243        newnode->type->variable->tyClass = tc;
244        newnode->type->variable->name = newnode->name;
245        return newnode;
246}
247
248DeclarationNode *DeclarationNode::newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) {
249        DeclarationNode *newnode = new DeclarationNode;
250        newnode->type = new TypeData( TypeData::Aggregate );
251        newnode->type->aggregate->kind = Context;
252        newnode->type->aggregate->params = params;
253        newnode->type->aggregate->members = asserts;
254        newnode->type->aggregate->name = assign_strptr( name );
255        return newnode;
256}
257
258DeclarationNode *DeclarationNode::newContextUse( std::string *name, ExpressionNode *params ) {
259        DeclarationNode *newnode = new DeclarationNode;
260        newnode->type = new TypeData( TypeData::AggregateInst );
261        newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
262        newnode->type->aggInst->aggregate->aggregate->kind = Context;
263        newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name );
264        newnode->type->aggInst->params = params;
265        return newnode;
266}
267
268DeclarationNode *DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) {
269        DeclarationNode *newnode = new DeclarationNode;
270        newnode->name = assign_strptr( name );
271        newnode->type = new TypeData( TypeData::Symbolic );
272        newnode->type->symbolic->isTypedef = false;
273        newnode->type->symbolic->params = typeParams;
274        newnode->type->symbolic->name = newnode->name;
275        return newnode;
276}
277
278DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) {
279        DeclarationNode *newnode = new DeclarationNode;
280        newnode->type = new TypeData( TypeData::Pointer );
281        return newnode->addQualifiers( qualifiers );
282}
283
284DeclarationNode *DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) {
285        DeclarationNode *newnode = new DeclarationNode;
286        newnode->type = new TypeData( TypeData::Array );
287        newnode->type->array->dimension = size;
288        newnode->type->array->isStatic = isStatic;
289        newnode->type->array->isVarLen = false;
290        return newnode->addQualifiers( qualifiers );
291}
292
293DeclarationNode *DeclarationNode::newVarArray( DeclarationNode *qualifiers ) {
294        DeclarationNode *newnode = new DeclarationNode;
295        newnode->type = new TypeData( TypeData::Array );
296        newnode->type->array->dimension = 0;
297        newnode->type->array->isStatic = false;
298        newnode->type->array->isVarLen = true;
299        return newnode->addQualifiers( qualifiers );
300}
301
302DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) {
303        DeclarationNode *newnode = new DeclarationNode;
304        newnode->bitfieldWidth = size;
305        return newnode;
306}
307
308DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) {
309        DeclarationNode *newnode = new DeclarationNode;
310        newnode->type = new TypeData( TypeData::Tuple );
311        newnode->type->tuple->members = members;
312        return newnode;
313}
314
315DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) {
316        DeclarationNode *newnode = new DeclarationNode;
317        newnode->type = new TypeData( TypeData::Typeof );
318        newnode->type->typeexpr->expr = expr;
319        return newnode;
320}
321
322DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) {
323        DeclarationNode *newnode = new DeclarationNode;
324        newnode->type = new TypeData( TypeData::Attr );
325        newnode->type->attr->name = assign_strptr( name );
326        newnode->type->attr->expr = expr;
327        return newnode;
328}
329
330DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) {
331        DeclarationNode *newnode = new DeclarationNode;
332        newnode->type = new TypeData( TypeData::Attr );
333        newnode->type->attr->name = assign_strptr( name );
334        newnode->type->attr->type = type;
335        return newnode;
336}
337
338static void addQualifiersToType( TypeData *&src, TypeData *dst ) {
339        if ( src && dst ) {
340                if ( src->forall && dst->kind == TypeData::Function ) {
341                        if ( dst->forall ) {
342                                dst->forall->appendList( src->forall );
343                        } else {
344                                dst->forall = src->forall;
345                        } // if
346                        src->forall = 0;
347                } // if
348                if ( dst->base ) {
349                        addQualifiersToType( src, dst->base );
350                } else if ( dst->kind == TypeData::Function ) {
351                        dst->base = src;
352                        src = 0;
353                } else {
354                        dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
355                } // if
356        } // if
357}
358         
359DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
360        if ( q ) {
361                storageClasses.splice( storageClasses.end(), q->storageClasses );
362                if ( q->type ) {
363                        if ( ! type ) {
364                                type = new TypeData;
365                        } // if
366                        addQualifiersToType( q->type, type );
367                        if ( q->type && q->type->forall ) {
368                                if ( type->forall ) {
369                                        type->forall->appendList( q->type->forall );
370                                } else {
371                                        if ( type->kind == TypeData::Aggregate ) {
372                                                type->aggregate->params = q->type->forall;
373                                        } else {
374                                                type->forall = q->type->forall;
375                                        } // if
376                                } // if
377                                q->type->forall = 0;
378                        } // if
379                } // if
380        } // if
381        delete q;
382        return this;
383}
384
385DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
386        storageClasses = q->storageClasses;
387        return this;
388}
389
390static void addTypeToType( TypeData *&src, TypeData *&dst ) {
391        if ( src && dst ) {
392                if ( src->forall && dst->kind == TypeData::Function ) {
393                        if ( dst->forall ) {
394                                dst->forall->appendList( src->forall );
395                        } else {
396                                dst->forall = src->forall;
397                        } // if
398                        src->forall = 0;
399                } // if
400                if ( dst->base ) {
401                        addTypeToType( src, dst->base );
402                } else {
403                        switch ( dst->kind ) {
404                          case TypeData::Unknown:
405                                src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
406                                dst = src;
407                                src = 0;
408                                break;
409
410                          case TypeData::Basic:
411                                dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
412                                if ( src->kind != TypeData::Unknown ) {
413                                        assert( src->kind == TypeData::Basic );
414                                        dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
415                                        dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
416                                } // if
417                                break;
418
419                          default:
420                                switch ( src->kind ) {
421                                  case TypeData::Aggregate:
422                                  case TypeData::Enum:
423                                        dst->base = new TypeData( TypeData::AggregateInst );
424                                        dst->base->aggInst->aggregate = src;
425                                        if ( src->kind == TypeData::Aggregate ) {
426                                                dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
427                                        } // if
428                                        dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
429                                        src = 0;
430                                        break;
431
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        } // if
471        delete o;
472        return this;
473}
474
475DeclarationNode *DeclarationNode::addTypedef() {
476        TypeData *newtype = new TypeData( TypeData::Symbolic );
477        newtype->symbolic->params = 0;
478        newtype->symbolic->isTypedef = true;
479        newtype->symbolic->name = name;
480        newtype->base = type;
481        type = newtype;
482        return this;
483}
484
485DeclarationNode *DeclarationNode::addAssertions( DeclarationNode *assertions ) {
486        assert( type );
487        switch ( type->kind ) {
488          case TypeData::Symbolic:
489                if ( type->symbolic->assertions ) {
490                        type->symbolic->assertions->appendList( assertions );
491                } else {
492                        type->symbolic->assertions = assertions;
493                } // if
494                break;
495          case TypeData::Variable:
496                if ( type->variable->assertions ) {
497                        type->variable->assertions->appendList( assertions );
498                } else {
499                        type->variable->assertions = assertions;
500                } // if
501                break;
502          default:
503                assert( false );
504        } // switch
505       
506        return this;
507}
508
509DeclarationNode *DeclarationNode::addName( std::string *newname ) {
510        name = assign_strptr( newname );
511        return this;
512}
513
514DeclarationNode *DeclarationNode::addBitfield( ExpressionNode *size ) {
515        bitfieldWidth = size;
516        return this;
517}
518
519DeclarationNode *DeclarationNode::addVarArgs() {
520        assert( type );
521        hasEllipsis = true;
522        return this;
523}
524
525DeclarationNode *DeclarationNode::addFunctionBody( StatementNode *body ) {
526        assert( type );
527        assert( type->kind == TypeData::Function );
528        assert( type->function->body == 0 );
529        type->function->body = body;
530        type->function->hasBody = true;
531        return this;
532}
533
534DeclarationNode *DeclarationNode::addOldDeclList( DeclarationNode *list ) {
535        assert( type );
536        assert( type->kind == TypeData::Function );
537        assert( type->function->oldDeclList == 0 );
538        type->function->oldDeclList = list;
539        return this;
540}
541
542static void setBase( TypeData *&type, TypeData *newType ) {
543        if ( type ) {
544                TypeData *prevBase = type;
545                TypeData *curBase = type->base;
546                while ( curBase != 0 ) {
547                        prevBase = curBase;
548                        curBase = curBase->base;
549                } // while
550                prevBase->base = newType;
551        } else {
552                type = newType;
553        } // if
554}
555
556DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) {
557        if ( p ) {
558                assert( p->type->kind == TypeData::Pointer );
559                setBase( type, p->type );
560                p->type = 0;
561                delete p;
562        } // if
563        return this;
564}
565
566DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) {
567        if ( a ) {
568                assert( a->type->kind == TypeData::Array );
569                setBase( type, a->type );
570                a->type = 0;
571                delete a;
572        } // if
573        return this;
574}
575
576DeclarationNode *DeclarationNode::addNewPointer( DeclarationNode *p ) {
577        if ( p ) {
578                assert( p->type->kind == TypeData::Pointer );
579                if ( type ) {
580                        switch ( type->kind ) {
581                          case TypeData::Aggregate:
582                          case TypeData::Enum:
583                                p->type->base = new TypeData( TypeData::AggregateInst );
584                                p->type->base->aggInst->aggregate = type;
585                                if ( type->kind == TypeData::Aggregate ) {
586                                        p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
587                                } // if
588                                p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
589                                break;
590
591                          default:
592                                p->type->base = type;
593                        } // switch
594                        type = 0;
595                } // if
596                delete this;
597                return p;
598        } else {
599                return this;
600        } // if
601}
602
603static TypeData *findLast( TypeData *a ) {
604        assert( a );
605        TypeData *cur = a;
606        while ( cur->base ) {
607                cur = cur->base;
608        } // while
609        return cur;
610}
611
612DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
613        if ( a ) {
614                assert( a->type->kind == TypeData::Array );
615                TypeData *lastArray = findLast( a->type );
616                if ( type ) { 
617                        switch ( type->kind ) {
618                          case TypeData::Aggregate:
619                          case TypeData::Enum:
620                                lastArray->base = new TypeData( TypeData::AggregateInst );
621                                lastArray->base->aggInst->aggregate = type;
622                                if ( type->kind == TypeData::Aggregate ) {
623                                        lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
624                                } // if
625                                lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
626                                break;
627                          default:
628                                lastArray->base = type;
629                        } // switch
630                        type = 0;
631                } // if
632                delete this;
633                return a;
634        } else {
635                return this;
636        } // if
637}
638
639DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
640        TypeData *ftype = new TypeData( TypeData::Function );
641        ftype->function->params = params;
642        setBase( type, ftype );
643        return this;
644}
645
646static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
647        if ( type ) {
648                if ( type->kind != TypeData::Function ) {
649                        type->base = addIdListToType( type->base, ids );
650                } else {
651                        type->function->idList = ids;
652                } // if
653                return type;
654        } else {
655                TypeData *newtype = new TypeData( TypeData::Function );
656                newtype->function->idList = ids;
657                return newtype;
658        } // if
659}
660       
661DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
662        type = addIdListToType( type, ids );
663        return this;
664}
665
666DeclarationNode *DeclarationNode::addInitializer( InitializerNode *init ) {
667        //assert
668        initializer = init;
669        return this;
670}
671
672DeclarationNode *DeclarationNode::cloneBaseType( string *newName ) {
673        DeclarationNode *newnode = new DeclarationNode;
674        TypeData *srcType = type;
675        while ( srcType->base ) {
676                srcType = srcType->base;
677        } // while
678        newnode->type = maybeClone( srcType );
679        if ( newnode->type->kind == TypeData::AggregateInst ) {
680                // don't duplicate members
681                if ( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
682                        delete newnode->type->aggInst->aggregate->enumeration->constants;
683                        newnode->type->aggInst->aggregate->enumeration->constants = 0;
684                } else {
685                        assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
686                        delete newnode->type->aggInst->aggregate->aggregate->members;
687                        newnode->type->aggInst->aggregate->aggregate->members = 0;
688                } // if
689        } // if
690        newnode->type->forall = maybeClone( type->forall );
691        newnode->storageClasses = storageClasses;
692        newnode->name = assign_strptr( newName );
693        return newnode;
694}
695
696DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
697        if ( o ) {
698                o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
699                if ( type ) {
700                        TypeData *srcType = type;
701                        while ( srcType->base ) {
702                                srcType = srcType->base;
703                        } // while
704                        TypeData *newType = srcType->clone();
705                        if ( newType->kind == TypeData::AggregateInst ) {
706                                // don't duplicate members
707                                if ( newType->aggInst->aggregate->kind == TypeData::Enum ) {
708                                        delete newType->aggInst->aggregate->enumeration->constants;
709                                        newType->aggInst->aggregate->enumeration->constants = 0;
710                                } else {
711                                        assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
712                                        delete newType->aggInst->aggregate->aggregate->members;
713                                        newType->aggInst->aggregate->aggregate->members = 0;
714                                } // if
715                        } // if
716                        newType->forall = maybeClone( type->forall );
717                        if ( ! o->type ) {
718                                o->type = newType;
719                        } else {
720                                addTypeToType( newType, o->type );
721                                delete newType;
722                        } // if
723                } // if
724        } // if
725        return o;
726}
727
728DeclarationNode *DeclarationNode::cloneType( string *newName ) {
729        DeclarationNode *newnode = new DeclarationNode;
730        newnode->type = maybeClone( type );
731        newnode->storageClasses = storageClasses;
732        newnode->name = assign_strptr( newName );
733        return newnode;
734}
735
736DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
737        if ( o ) {
738                o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
739                if ( type ) {
740                        TypeData *newType = type->clone();
741                        if ( ! o->type ) {
742                                o->type = newType;
743                        } else {
744                                addTypeToType( newType, o->type );
745                                delete newType;
746                        } // if
747                } // if
748        } // if
749        return o;
750}
751
752DeclarationNode *DeclarationNode::appendList( DeclarationNode *node ) {
753        if ( node != 0 ) {
754                set_link( node );
755        } // if
756        return this;
757}
758
759DeclarationNode *DeclarationNode::extractAggregate() const {
760        if ( type ) {
761                TypeData *ret = type->extractAggregate();
762                if ( ret ) {
763                        DeclarationNode *newnode = new DeclarationNode;
764                        newnode->type = ret;
765                        return newnode;
766                } // if
767        } // if
768        return 0;
769}
770
771void buildList( const DeclarationNode *firstNode, std::list< Declaration * > &outputList ) {
772        SemanticError errors;
773        std::back_insert_iterator< std::list< Declaration *> > out( outputList );
774        const DeclarationNode *cur = firstNode;
775        while ( cur ) {
776                try {
777                        if ( DeclarationNode *extr = cur->extractAggregate() ) {
778                                // handle the case where a structure declaration is contained within an object or type declaration
779                                Declaration *decl = extr->build();
780                                if ( decl ) {
781                                        *out++ = decl;
782                                } // if
783                        } // if
784                        Declaration *decl = cur->build();
785                        if ( decl ) {
786                                *out++ = decl;
787                        } // if
788                } catch( SemanticError &e ) {
789                        errors.append( e );
790                } // try
791                cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
792        } // while
793        if ( ! errors.isEmpty() ) {
794                throw errors;
795        } // if
796}
797
798void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType *> &outputList ) {
799        SemanticError errors;
800        std::back_insert_iterator< std::list< DeclarationWithType *> > out( outputList );
801        const DeclarationNode *cur = firstNode;
802        while ( cur ) {
803                try {
804///       if ( DeclarationNode *extr = cur->extractAggregate() ) {
805///     // handle the case where a structure declaration is contained within an object or type
806///     // declaration
807///     Declaration *decl = extr->build();
808///     if ( decl ) {
809///          *out++ = decl;
810///     }
811///       }
812                        Declaration *decl = cur->build();
813                        if ( decl ) {
814                                if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {
815                                        *out++ = dwt;
816                                } else if ( StructDecl *agg = dynamic_cast< StructDecl *>( decl ) ) {
817                                        StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
818                                        *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
819                                        delete agg;
820                                } else if ( UnionDecl *agg = dynamic_cast< UnionDecl *>( decl ) ) {
821                                        UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
822                                        *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
823                                } // if
824                        } // if
825                } catch( SemanticError &e ) {
826                        errors.append( e );
827                } // try
828                cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
829        } // while
830        if ( ! errors.isEmpty() ) {
831                throw errors;
832        } // if
833}
834
835void buildTypeList( const DeclarationNode *firstNode, std::list< Type *> &outputList ) {
836        SemanticError errors;
837        std::back_insert_iterator< std::list< Type *> > out( outputList );
838        const DeclarationNode *cur = firstNode;
839        while ( cur ) {
840                try {
841                        *out++ = cur->buildType();
842                } catch( SemanticError &e ) {
843                        errors.append( e );
844                } // try
845                cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
846        } // while
847        if ( ! errors.isEmpty() ) {
848                throw errors;
849        } // if
850}
851
852Declaration *DeclarationNode::build() const {
853        if ( type ) {
854                Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildFuncSpecifier( Inline ), buildFuncSpecifier( Noreturn ), linkage, maybeBuild< Initializer >(initializer) );
855                return newDecl;
856        } // if
857        if ( ! buildFuncSpecifier( Inline ) && ! buildFuncSpecifier( Noreturn ) ) {
858                return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
859        } // if
860        throw SemanticError( "invalid function specifier in declaration of ", this );
861}
862
863Type *DeclarationNode::buildType() const {
864        assert( type );
865 
866        switch ( type->kind ) {
867          case TypeData::Enum:
868                return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
869          case TypeData::Aggregate: {
870                  ReferenceToType *ret;
871                  switch ( type->aggregate->kind ) {
872                        case DeclarationNode::Struct:
873                          ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
874                          break;
875                        case DeclarationNode::Union:
876                          ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
877                          break;
878                        case DeclarationNode::Context:
879                          ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
880                          break;
881                        default:
882                          assert( false );
883                  } // switch
884                  buildList( type->aggregate->actuals, ret->get_parameters() );
885                  return ret;
886          }
887          case TypeData::Symbolic: {
888                  TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
889                  buildList( type->symbolic->actuals, ret->get_parameters() );
890                  return ret;
891          }
892          default:
893                return type->build();
894        } // switch
895}
896
897DeclarationNode::StorageClass DeclarationNode::buildStorageClass() const {
898        DeclarationNode::StorageClass ret = DeclarationNode::NoStorageClass;
899        for ( std::list< DeclarationNode::StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
900          if ( *i == DeclarationNode::Inline || *i == DeclarationNode::Noreturn ) continue; // ignore function specifiers
901          if ( ret != DeclarationNode::NoStorageClass ) {       // already have a valid storage class ?
902                        throw SemanticError( "invalid combination of storage classes in declaration of ", this );
903                } // if
904                ret = *i;
905        } // for
906        return ret;
907}
908
909bool DeclarationNode::buildFuncSpecifier( DeclarationNode::StorageClass key ) const {
910        std::list< DeclarationNode::StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), key );
911  if ( first == storageClasses.end() ) return false;    // not found
912        first = std::find( ++first, storageClasses.end(), key ); // found
913  if ( first == storageClasses.end() ) return true;             // not found again
914        throw SemanticError( "duplicate function specifier in declaration of ", this );
915}
916
917// Local Variables: //
918// tab-width: 4 //
919// mode: c++ //
920// compile-command: "make install" //
921// End: //
Note: See TracBrowser for help on using the repository browser.