source: src/Parser/DeclarationNode.cc@ e0ff3e6

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 e0ff3e6 was de62360d, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

fix computed goto, fixed -std=, implicit typedefs for enum and aggregates, add _Noreturn _Thread_local

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