source: src/Parser/DeclarationNode.cc @ 8e9cbb2

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

add more code to handle gcc extension and test program, second attempt

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