source: src/Parser/DeclarationNode.cc @ 2cdf6dc

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 2cdf6dc was 44a81853, checked in by Peter A. Buhr <pabuhr@…>, 8 years ago

first attempt at gcc attributes

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