source: translator/Parser/DeclarationNode.cc@ d0e8cfe4

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 d0e8cfe4 was 8c17ab0, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

add quoted identifiers, add compilation include directory, reformatted some files

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