source: src/Parser/DeclarationNode.cc @ 3365b37

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 3365b37 was 45161b4d, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

generate implicit typedef right after sue name appears, further fixes storage allocation routines and comments

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