source: src/Parser/DeclarationNode.cc @ c09e4bc

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since c09e4bc was 13e3b50, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

DeclarationNodes? and Declaration now store exactly the same data for storage classes

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