source: translator/Parser/DeclarationNode.cc@ fe3b61b

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

fixed restrict, fixed parameter copy, introduced name table for types, changed variable after to string

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