source: src/Parser/DeclarationNode.cc @ 68cd1ce

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 68cd1ce was 68cd1ce, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

unify and fix storage class

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