source: translator/Parser/DeclarationNode.cc@ a0d9f94

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 a0d9f94 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

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