source: src/Parser/DeclarationNode.cc @ 6244dfb

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

licencing: seventh groups of files

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