source: src/Parser/DeclarationNode.cc @ b6424d9

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

refactor copyStorageClasses

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