source: src/Parser/DeclarationNode.cc @ fc4a0fa

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since fc4a0fa was 101e0bd, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

more refactoring of parser code

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