source: translator/Parser/DeclarationNode.cc @ 3848e0e

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 3848e0e was 3848e0e, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

underscore changes, ptrdiff_t changes, formating, _Bool prelude

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