source: src/Parser/DeclarationNode.cc @ 0df292b

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 0df292b was 721f17a, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

fix OT_LABELADDRESS warning, parse genric types

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