source: src/Parser/DeclarationNode.cc @ fb114fa1

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

more refactoring of parser code

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