source: src/Parser/DeclarationNode.cc @ 02c7d04

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 02c7d04 was 974906e2, checked in by Rob Schluntz <rschlunt@…>, 9 years ago

propagate maybeConstructed flag through system, begin create constructor/destructor statements for further processing by Resolver

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