source: src/Parser/DeclarationNode.cc @ 4f147cc

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 4f147cc was 4f147cc, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

fixed some more memory leaks and added safe_dynamic_cast to assert.h

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