source: src/Parser/DeclarationNode.cc@ 2bae7307

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 2bae7307 was 843054c2, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

licencing: seventh groups of files

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