source: src/Parser/DeclarationNode.cc @ e7b2559

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since e7b2559 was 5d125e4, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

start code allowing structures to no fields

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