source: translator/Parser/DeclarationNode.cc @ a08ba92

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 a08ba92 was a32b204, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

licencing: second groups of files

  • Property mode set to 100644
File size: 27.1 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 : Sat May 16 12:38:20 2015
13// Update Count     : 4
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                } else {
754                        return 0;
755                }
756        } else {
757                return 0;
758        }
759}
760
761void buildList( const DeclarationNode *firstNode, std::list< Declaration* > &outputList ) {
762        SemanticError errors;
763        std::back_insert_iterator< std::list< Declaration* > > out( outputList );
764        const DeclarationNode *cur = firstNode;
765        while ( cur ) {
766                try {
767                        if ( DeclarationNode *extr = cur->extractAggregate() ) {
768                                // handle the case where a structure declaration is contained within an object or type declaration
769                                Declaration *decl = extr->build();
770                                if ( decl ) {
771                                        *out++ = decl;
772                                }
773                        }
774                        Declaration *decl = cur->build();
775                        if ( decl ) {
776                                *out++ = decl;
777                        }
778                } catch( SemanticError &e ) {
779                        errors.append( e );
780                }
781                cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
782        }
783        if ( ! errors.isEmpty() ) {
784                throw errors;
785        }
786}
787
788void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType* > &outputList ) {
789        SemanticError errors;
790        std::back_insert_iterator< std::list< DeclarationWithType* > > out( outputList );
791        const DeclarationNode *cur = firstNode;
792        while ( cur ) {
793                try {
794///       if ( DeclarationNode *extr = cur->extractAggregate() ) {
795///     // handle the case where a structure declaration is contained within an object or type
796///     // declaration
797///     Declaration *decl = extr->build();
798///     if ( decl ) {
799///          *out++ = decl;
800///     }
801///       }
802                        Declaration *decl = cur->build();
803                        if ( decl ) {
804                                if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
805                                        *out++ = dwt;
806                                } else if ( StructDecl *agg = dynamic_cast< StructDecl* >( decl ) ) {
807                                        StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
808                                        *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
809                                        delete agg;
810                                } else if ( UnionDecl *agg = dynamic_cast< UnionDecl* >( decl ) ) {
811                                        UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
812                                        *out++ = new ObjectDecl( "", Declaration::NoStorageClass, linkage, 0, inst, 0 );
813                                }
814                        }
815                } catch( SemanticError &e ) {
816                        errors.append( e );
817                }
818                cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
819        }
820        if ( ! errors.isEmpty() ) {
821                throw errors;
822        }
823}
824
825void buildTypeList( const DeclarationNode *firstNode, std::list< Type* > &outputList ) {
826        SemanticError errors;
827        std::back_insert_iterator< std::list< Type* > > out( outputList );
828        const DeclarationNode *cur = firstNode;
829        while ( cur ) {
830                try {
831                        *out++ = cur->buildType();
832                } catch( SemanticError &e ) {
833                        errors.append( e );
834                }
835                cur = dynamic_cast< DeclarationNode* >( cur->get_link() );
836        }
837        if ( ! errors.isEmpty() ) {
838                throw errors;
839        }
840}
841
842Declaration *DeclarationNode::build() const {
843
844        if ( ! type ) {
845                if ( buildInline() ) {
846                        throw SemanticError( "invalid inline specification in declaration of ", this );
847                } else {
848                        return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
849                }
850        } else {
851                Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildInline(), linkage, maybeBuild< Initializer >(initializer) );
852                return newDecl;
853        }
854        // we should never get here
855        assert( false );
856        return 0;
857}
858
859Type *DeclarationNode::buildType() const {
860        assert( type );
861 
862        switch ( type->kind ) {
863          case TypeData::Enum:
864                return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
865          case TypeData::Aggregate: {
866                  ReferenceToType *ret;
867                  switch ( type->aggregate->kind ) {
868                        case DeclarationNode::Struct:
869                          ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
870                          break;
871                        case DeclarationNode::Union:
872                          ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
873                          break;
874                        case DeclarationNode::Context:
875                          ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
876                          break;
877                        default:
878                          assert( false );
879                  } // switch
880                  buildList( type->aggregate->actuals, ret->get_parameters() );
881                  return ret;
882          }
883          case TypeData::Symbolic: {
884                  TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
885                  buildList( type->symbolic->actuals, ret->get_parameters() );
886                  return ret;
887          }
888          default:
889                return type->build();
890        } // switch
891}
892
893Declaration::StorageClass DeclarationNode::buildStorageClass() const {
894        static const Declaration::StorageClass scMap[] = { 
895                Declaration::Extern,
896                Declaration::Static,
897                Declaration::Auto,
898                Declaration::Register,
899                Declaration::Inline,
900                Declaration::Fortran
901        }; 
902 
903        Declaration::StorageClass ret = Declaration::NoStorageClass;
904        for ( std::list< StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
905                assert( unsigned( *i ) < sizeof( scMap ) / sizeof( scMap[0] ) );
906                if ( *i == Inline ) continue;
907                if ( ret == Declaration::NoStorageClass ) {
908                        ret = scMap[ *i ];
909                } else {
910                        throw SemanticError( "invalid combination of storage classes in declaration of ", this );
911                }
912        }
913        return ret;
914}
915
916bool DeclarationNode::buildInline() const {
917        std::list< StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), Inline );
918        if ( first == storageClasses.end() ) {
919                return false;
920        } else {
921                std::list< StorageClass >::const_iterator next = std::find( ++first, storageClasses.end(), Inline );
922                if ( next == storageClasses.end() ) {
923                        return true;
924                } else {
925                        throw SemanticError( "duplicate inline specification in declaration of ", this );
926                }
927        }
928        // we should never get here
929        return false;
930}
931
932// Local Variables: //
933// tab-width: 4 //
934// mode: c++ //
935// compile-command: "make install" //
936// End: //
Note: See TracBrowser for help on using the repository browser.