source: translator/Parser.old/DeclarationNode.cc@ c8ffe20b

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since c8ffe20b was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

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