source: src/Parser/DeclarationNode.cc @ 5ba653c

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 5ba653c was 984dce6, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

only implicitly generate typedef for structures if name not in use and overwrite typedef name if explicit name appears, upate parser symbol table

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