source: translator/Parser/DeclarationNode.cc@ d4778a6

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

fixed sizeof type variable, find lowest cost alternative for sizeof expression, removed unused classes, added compiler flag, remove temporary file for -CFA, formatting

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