source: src/Parser/DeclarationNode.cc @ 7bf7fb9

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

more refactoring of parser code

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