source: src/Parser/DeclarationNode.cc @ 4040425

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglergc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newstringwith_gc
Last change on this file since 4040425 was 4040425, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

change keyword type to otype and context to trait

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