source: src/Parser/DeclarationNode.cc @ aa8f9df

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 aa8f9df was b6424d9, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

refactor copyStorageClasses

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