source: src/Parser/DeclarationNode.cc @ 413ad05

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

more refactoring of parser code

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