source: src/Parser/DeclarationNode.cc@ cff1143

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 cff1143 was 71bd8c6, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

fix isVarLen in array types, fix loss of typedef when variable of aggregate type is declared, fix duplicate typedef with arrays of constant size

  • Property mode set to 100644
File size: 28.9 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 : Rob Schluntz
12// Last Modified On : Wed Jul 08 16:40:37 2015
13// Update Count : 121
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, const std::string *name, 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 == "" ) { // anonymous aggregate ?
181 newnode->type->aggregate->name = DeclarationNode::anonymous.newName();
182 } else {
183 // SKULLDUGGERY: generate a typedef for the aggregate name so that the aggregate does not have to be qualified
184 // by "struct"
185 typedefTable.addToEnclosingScope( newnode->type->aggregate->name, TypedefTable::TD );
186 DeclarationNode *typedf = new DeclarationNode;
187 typedf->name = newnode->type->aggregate->name;
188 newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );
189 } // if
190 newnode->type->aggregate->actuals = actuals;
191 newnode->type->aggregate->fields = fields;
192 return newnode;
193}
194
195DeclarationNode *DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) {
196 DeclarationNode *newnode = new DeclarationNode;
197 newnode->name = assign_strptr( name );
198 newnode->type = new TypeData( TypeData::Enum );
199 newnode->type->enumeration->name = newnode->name;
200 if ( newnode->type->enumeration->name == "" ) { // anonymous enumeration ?
201 newnode->type->enumeration->name = DeclarationNode::anonymous.newName();
202 } else {
203 // SKULLDUGGERY: generate a typedef for the enumeration name so that the enumeration does not have to be
204 // qualified by "enum"
205 typedefTable.addToEnclosingScope( newnode->type->enumeration->name, TypedefTable::TD );
206 DeclarationNode *typedf = new DeclarationNode;
207 typedf->name = newnode->type->enumeration->name;
208 newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );
209 } // if
210 newnode->type->enumeration->constants = constants;
211 return newnode;
212}
213
214DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) {
215 DeclarationNode *newnode = new DeclarationNode;
216 newnode->name = assign_strptr( name );
217 // do something with the constant
218 return newnode;
219}
220
221DeclarationNode *DeclarationNode::newName( std::string *name ) {
222 DeclarationNode *newnode = new DeclarationNode;
223 newnode->name = assign_strptr( name );
224 return newnode;
225}
226
227DeclarationNode *DeclarationNode::newFromTypeGen( std::string *name, ExpressionNode *params ) {
228 DeclarationNode *newnode = new DeclarationNode;
229 newnode->type = new TypeData( TypeData::SymbolicInst );
230 newnode->type->symbolic->name = assign_strptr( name );
231 newnode->type->symbolic->isTypedef = false;
232 newnode->type->symbolic->actuals = params;
233 return newnode;
234}
235
236DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string *name ) {
237 DeclarationNode *newnode = new DeclarationNode;
238 newnode->name = assign_strptr( name );
239 newnode->type = new TypeData( TypeData::Variable );
240 newnode->type->variable->tyClass = tc;
241 newnode->type->variable->name = newnode->name;
242 return newnode;
243}
244
245DeclarationNode *DeclarationNode::newContext( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) {
246 DeclarationNode *newnode = new DeclarationNode;
247 newnode->type = new TypeData( TypeData::Aggregate );
248 newnode->type->aggregate->kind = Context;
249 newnode->type->aggregate->params = params;
250 newnode->type->aggregate->fields = asserts;
251 newnode->type->aggregate->name = assign_strptr( name );
252 return newnode;
253}
254
255DeclarationNode *DeclarationNode::newContextUse( std::string *name, ExpressionNode *params ) {
256 DeclarationNode *newnode = new DeclarationNode;
257 newnode->type = new TypeData( TypeData::AggregateInst );
258 newnode->type->aggInst->aggregate = new TypeData( TypeData::Aggregate );
259 newnode->type->aggInst->aggregate->aggregate->kind = Context;
260 newnode->type->aggInst->aggregate->aggregate->name = assign_strptr( name );
261 newnode->type->aggInst->params = params;
262 return newnode;
263}
264
265DeclarationNode *DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) {
266 DeclarationNode *newnode = new DeclarationNode;
267 newnode->name = assign_strptr( name );
268 newnode->type = new TypeData( TypeData::Symbolic );
269 newnode->type->symbolic->isTypedef = false;
270 newnode->type->symbolic->params = typeParams;
271 newnode->type->symbolic->name = newnode->name;
272 return newnode;
273}
274
275DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) {
276 DeclarationNode *newnode = new DeclarationNode;
277 newnode->type = new TypeData( TypeData::Pointer );
278 return newnode->addQualifiers( qualifiers );
279}
280
281DeclarationNode *DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) {
282 DeclarationNode *newnode = new DeclarationNode;
283 newnode->type = new TypeData( TypeData::Array );
284 newnode->type->array->dimension = size;
285 newnode->type->array->isStatic = isStatic;
286 if ( newnode->type->array->dimension == 0 || dynamic_cast<ConstantNode *>( newnode->type->array->dimension ) ) {
287 newnode->type->array->isVarLen = false;
288 } else {
289 newnode->type->array->isVarLen = true;
290 } // if
291 return newnode->addQualifiers( qualifiers );
292}
293
294DeclarationNode *DeclarationNode::newVarArray( DeclarationNode *qualifiers ) {
295 DeclarationNode *newnode = new DeclarationNode;
296 newnode->type = new TypeData( TypeData::Array );
297 newnode->type->array->dimension = 0;
298 newnode->type->array->isStatic = false;
299 newnode->type->array->isVarLen = true;
300 return newnode->addQualifiers( qualifiers );
301}
302
303DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) {
304 DeclarationNode *newnode = new DeclarationNode;
305 newnode->bitfieldWidth = size;
306 return newnode;
307}
308
309DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) {
310 DeclarationNode *newnode = new DeclarationNode;
311 newnode->type = new TypeData( TypeData::Tuple );
312 newnode->type->tuple->members = members;
313 return newnode;
314}
315
316DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) {
317 DeclarationNode *newnode = new DeclarationNode;
318 newnode->type = new TypeData( TypeData::Typeof );
319 newnode->type->typeexpr->expr = expr;
320 return newnode;
321}
322
323DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) {
324 DeclarationNode *newnode = new DeclarationNode;
325 newnode->type = new TypeData( TypeData::Attr );
326 newnode->type->attr->name = assign_strptr( name );
327 newnode->type->attr->expr = expr;
328 return newnode;
329}
330
331DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) {
332 DeclarationNode *newnode = new DeclarationNode;
333 newnode->type = new TypeData( TypeData::Attr );
334 newnode->type->attr->name = assign_strptr( name );
335 newnode->type->attr->type = type;
336 return newnode;
337}
338
339static void addQualifiersToType( TypeData *&src, TypeData *dst ) {
340 if ( src && dst ) {
341 if ( src->forall && dst->kind == TypeData::Function ) {
342 if ( dst->forall ) {
343 dst->forall->appendList( src->forall );
344 } else {
345 dst->forall = src->forall;
346 } // if
347 src->forall = 0;
348 } // if
349 if ( dst->base ) {
350 addQualifiersToType( src, dst->base );
351 } else if ( dst->kind == TypeData::Function ) {
352 dst->base = src;
353 src = 0;
354 } else {
355 dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
356 } // if
357 } // if
358}
359
360DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
361 if ( q ) {
362 storageClasses.splice( storageClasses.end(), q->storageClasses );
363 if ( q->type ) {
364 if ( ! type ) {
365 type = new TypeData;
366 } // if
367 addQualifiersToType( q->type, type );
368 if ( q->type && q->type->forall ) {
369 if ( type->forall ) {
370 type->forall->appendList( q->type->forall );
371 } else {
372 if ( type->kind == TypeData::Aggregate ) {
373 type->aggregate->params = q->type->forall;
374 // change implicit typedef from TYPEDEFname to TYPEGENname
375 typedefTable.changeKind( type->aggregate->name, TypedefTable::TG );
376 } else {
377 type->forall = q->type->forall;
378 } // if
379 } // if
380 q->type->forall = 0;
381 } // if
382 } // if
383 } // if
384 delete q;
385 return this;
386}
387
388DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
389 storageClasses = q->storageClasses;
390 return this;
391}
392
393static void addTypeToType( TypeData *&src, TypeData *&dst ) {
394 if ( src && dst ) {
395 if ( src->forall && dst->kind == TypeData::Function ) {
396 if ( dst->forall ) {
397 dst->forall->appendList( src->forall );
398 } else {
399 dst->forall = src->forall;
400 } // if
401 src->forall = 0;
402 } // if
403 if ( dst->base ) {
404 addTypeToType( src, dst->base );
405 } else {
406 switch ( dst->kind ) {
407 case TypeData::Unknown:
408 src->qualifiers.splice( src->qualifiers.end(), dst->qualifiers );
409 dst = src;
410 src = 0;
411 break;
412 case TypeData::Basic:
413 dst->qualifiers.splice( dst->qualifiers.end(), src->qualifiers );
414 if ( src->kind != TypeData::Unknown ) {
415 assert( src->kind == TypeData::Basic );
416 dst->basic->modifiers.splice( dst->basic->modifiers.end(), src->basic->modifiers );
417 dst->basic->typeSpec.splice( dst->basic->typeSpec.end(), src->basic->typeSpec );
418 } // if
419 break;
420 default:
421 switch ( src->kind ) {
422 case TypeData::Aggregate:
423 case TypeData::Enum:
424 dst->base = new TypeData( TypeData::AggregateInst );
425 dst->base->aggInst->aggregate = src;
426 if ( src->kind == TypeData::Aggregate ) {
427 dst->base->aggInst->params = maybeClone( src->aggregate->actuals );
428 } // if
429 dst->base->qualifiers.splice( dst->base->qualifiers.end(), src->qualifiers );
430 src = 0;
431 break;
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
471 // there may be typedefs chained onto the type
472 if ( o->get_link() ) {
473 set_link( o->get_link()->clone() );
474 }
475
476 } // if
477 delete o;
478 return this;
479}
480
481DeclarationNode *DeclarationNode::addTypedef() {
482 TypeData *newtype = new TypeData( TypeData::Symbolic );
483 newtype->symbolic->params = 0;
484 newtype->symbolic->isTypedef = true;
485 newtype->symbolic->name = name;
486 newtype->base = type;
487 type = newtype;
488 return this;
489}
490
491DeclarationNode *DeclarationNode::addAssertions( DeclarationNode *assertions ) {
492 assert( type );
493 switch ( type->kind ) {
494 case TypeData::Symbolic:
495 if ( type->symbolic->assertions ) {
496 type->symbolic->assertions->appendList( assertions );
497 } else {
498 type->symbolic->assertions = assertions;
499 } // if
500 break;
501 case TypeData::Variable:
502 if ( type->variable->assertions ) {
503 type->variable->assertions->appendList( assertions );
504 } else {
505 type->variable->assertions = assertions;
506 } // if
507 break;
508 default:
509 assert( false );
510 } // switch
511
512 return this;
513}
514
515DeclarationNode *DeclarationNode::addName( std::string *newname ) {
516 name = assign_strptr( newname );
517 return this;
518}
519
520DeclarationNode *DeclarationNode::addBitfield( ExpressionNode *size ) {
521 bitfieldWidth = size;
522 return this;
523}
524
525DeclarationNode *DeclarationNode::addVarArgs() {
526 assert( type );
527 hasEllipsis = true;
528 return this;
529}
530
531DeclarationNode *DeclarationNode::addFunctionBody( StatementNode *body ) {
532 assert( type );
533 assert( type->kind == TypeData::Function );
534 assert( type->function->body == 0 );
535 type->function->body = body;
536 type->function->hasBody = true;
537 return this;
538}
539
540DeclarationNode *DeclarationNode::addOldDeclList( DeclarationNode *list ) {
541 assert( type );
542 assert( type->kind == TypeData::Function );
543 assert( type->function->oldDeclList == 0 );
544 type->function->oldDeclList = list;
545 return this;
546}
547
548static void setBase( TypeData *&type, TypeData *newType ) {
549 if ( type ) {
550 TypeData *prevBase = type;
551 TypeData *curBase = type->base;
552 while ( curBase != 0 ) {
553 prevBase = curBase;
554 curBase = curBase->base;
555 } // while
556 prevBase->base = newType;
557 } else {
558 type = newType;
559 } // if
560}
561
562DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) {
563 if ( p ) {
564 assert( p->type->kind == TypeData::Pointer );
565 setBase( type, p->type );
566 p->type = 0;
567 delete p;
568 } // if
569 return this;
570}
571
572DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) {
573 if ( a ) {
574 assert( a->type->kind == TypeData::Array );
575 setBase( type, a->type );
576 a->type = 0;
577 delete a;
578 } // if
579 return this;
580}
581
582DeclarationNode *DeclarationNode::addNewPointer( DeclarationNode *p ) {
583 if ( p ) {
584 assert( p->type->kind == TypeData::Pointer );
585 if ( type ) {
586 switch ( type->kind ) {
587 case TypeData::Aggregate:
588 case TypeData::Enum:
589 p->type->base = new TypeData( TypeData::AggregateInst );
590 p->type->base->aggInst->aggregate = type;
591 if ( type->kind == TypeData::Aggregate ) {
592 p->type->base->aggInst->params = maybeClone( type->aggregate->actuals );
593 } // if
594 p->type->base->qualifiers.splice( p->type->base->qualifiers.end(), type->qualifiers );
595 break;
596
597 default:
598 p->type->base = type;
599 } // switch
600 type = 0;
601 } // if
602 delete this;
603 return p;
604 } else {
605 return this;
606 } // if
607}
608
609static TypeData *findLast( TypeData *a ) {
610 assert( a );
611 TypeData *cur = a;
612 while ( cur->base ) {
613 cur = cur->base;
614 } // while
615 return cur;
616}
617
618DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
619 if ( a ) {
620 assert( a->type->kind == TypeData::Array );
621 TypeData *lastArray = findLast( a->type );
622 if ( type ) {
623 switch ( type->kind ) {
624 case TypeData::Aggregate:
625 case TypeData::Enum:
626 lastArray->base = new TypeData( TypeData::AggregateInst );
627 lastArray->base->aggInst->aggregate = type;
628 if ( type->kind == TypeData::Aggregate ) {
629 lastArray->base->aggInst->params = maybeClone( type->aggregate->actuals );
630 } // if
631 lastArray->base->qualifiers.splice( lastArray->base->qualifiers.end(), type->qualifiers );
632 break;
633 default:
634 lastArray->base = type;
635 } // switch
636 type = 0;
637 } // if
638 delete this;
639 return a;
640 } else {
641 return this;
642 } // if
643}
644
645DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
646 TypeData *ftype = new TypeData( TypeData::Function );
647 ftype->function->params = params;
648 setBase( type, ftype );
649 return this;
650}
651
652static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
653 if ( type ) {
654 if ( type->kind != TypeData::Function ) {
655 type->base = addIdListToType( type->base, ids );
656 } else {
657 type->function->idList = ids;
658 } // if
659 return type;
660 } else {
661 TypeData *newtype = new TypeData( TypeData::Function );
662 newtype->function->idList = ids;
663 return newtype;
664 } // if
665}
666
667DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
668 type = addIdListToType( type, ids );
669 return this;
670}
671
672DeclarationNode *DeclarationNode::addInitializer( InitializerNode *init ) {
673 //assert
674 initializer = init;
675 return this;
676}
677
678DeclarationNode *DeclarationNode::cloneBaseType( string *newName ) {
679 DeclarationNode *newnode = new DeclarationNode;
680 TypeData *srcType = type;
681 while ( srcType->base ) {
682 srcType = srcType->base;
683 } // while
684 newnode->type = maybeClone( srcType );
685 if ( newnode->type->kind == TypeData::AggregateInst ) {
686 // don't duplicate members
687 if ( newnode->type->aggInst->aggregate->kind == TypeData::Enum ) {
688 delete newnode->type->aggInst->aggregate->enumeration->constants;
689 newnode->type->aggInst->aggregate->enumeration->constants = 0;
690 } else {
691 assert( newnode->type->aggInst->aggregate->kind == TypeData::Aggregate );
692 delete newnode->type->aggInst->aggregate->aggregate->fields;
693 newnode->type->aggInst->aggregate->aggregate->fields = 0;
694 } // if
695 } // if
696 newnode->type->forall = maybeClone( type->forall );
697 newnode->storageClasses = storageClasses;
698 newnode->name = assign_strptr( newName );
699 return newnode;
700}
701
702DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
703 if ( o ) {
704 o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
705 if ( type ) {
706 TypeData *srcType = type;
707 while ( srcType->base ) {
708 srcType = srcType->base;
709 } // while
710 TypeData *newType = srcType->clone();
711 if ( newType->kind == TypeData::AggregateInst ) {
712 // don't duplicate members
713 if ( newType->aggInst->aggregate->kind == TypeData::Enum ) {
714 delete newType->aggInst->aggregate->enumeration->constants;
715 newType->aggInst->aggregate->enumeration->constants = 0;
716 } else {
717 assert( newType->aggInst->aggregate->kind == TypeData::Aggregate );
718 delete newType->aggInst->aggregate->aggregate->fields;
719 newType->aggInst->aggregate->aggregate->fields = 0;
720 } // if
721 } // if
722 newType->forall = maybeClone( type->forall );
723 if ( ! o->type ) {
724 o->type = newType;
725 } else {
726 addTypeToType( newType, o->type );
727 delete newType;
728 } // if
729 } // if
730 } // if
731 return o;
732}
733
734DeclarationNode *DeclarationNode::cloneType( string *newName ) {
735 DeclarationNode *newnode = new DeclarationNode;
736 newnode->type = maybeClone( type );
737 newnode->storageClasses = storageClasses;
738 newnode->name = assign_strptr( newName );
739 return newnode;
740}
741
742DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
743 if ( o ) {
744 o->storageClasses.insert( o->storageClasses.end(), storageClasses.begin(), storageClasses.end() );
745 if ( type ) {
746 TypeData *newType = type->clone();
747 if ( ! o->type ) {
748 o->type = newType;
749 } else {
750 addTypeToType( newType, o->type );
751 delete newType;
752 } // if
753 } // if
754 } // if
755 return o;
756}
757
758DeclarationNode *DeclarationNode::appendList( DeclarationNode *node ) {
759 if ( node != 0 ) {
760 set_link( node );
761 } // if
762 return this;
763}
764
765DeclarationNode *DeclarationNode::extractAggregate() const {
766 if ( type ) {
767 TypeData *ret = type->extractAggregate();
768 if ( ret ) {
769 DeclarationNode *newnode = new DeclarationNode;
770 newnode->type = ret;
771 return newnode;
772 } // if
773 } // if
774 return 0;
775}
776
777void buildList( const DeclarationNode *firstNode, std::list< Declaration * > &outputList ) {
778 SemanticError errors;
779 std::back_insert_iterator< std::list< Declaration *> > out( outputList );
780 const DeclarationNode *cur = firstNode;
781 while ( cur ) {
782 try {
783 if ( DeclarationNode *extr = cur->extractAggregate() ) {
784 // handle the case where a structure declaration is contained within an object or type declaration
785 Declaration *decl = extr->build();
786 if ( decl ) {
787 *out++ = decl;
788 } // if
789 } // if
790 Declaration *decl = cur->build();
791 if ( decl ) {
792 *out++ = decl;
793 } // if
794 } catch( SemanticError &e ) {
795 errors.append( e );
796 } // try
797 cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
798 } // while
799 if ( ! errors.isEmpty() ) {
800 throw errors;
801 } // if
802}
803
804void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType *> &outputList ) {
805 SemanticError errors;
806 std::back_insert_iterator< std::list< DeclarationWithType *> > out( outputList );
807 const DeclarationNode *cur = firstNode;
808 while ( cur ) {
809 try {
810/// if ( DeclarationNode *extr = cur->extractAggregate() ) {
811/// // handle the case where a structure declaration is contained within an object or type
812/// // declaration
813/// Declaration *decl = extr->build();
814/// if ( decl ) {
815/// *out++ = decl;
816/// }
817/// }
818 Declaration *decl = cur->build();
819 if ( decl ) {
820 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {
821 *out++ = dwt;
822 } else if ( StructDecl *agg = dynamic_cast< StructDecl *>( decl ) ) {
823 StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
824 *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
825 delete agg;
826 } else if ( UnionDecl *agg = dynamic_cast< UnionDecl *>( decl ) ) {
827 UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
828 *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
829 } // if
830 } // if
831 } catch( SemanticError &e ) {
832 errors.append( e );
833 } // try
834 cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
835 } // while
836 if ( ! errors.isEmpty() ) {
837 throw errors;
838 } // if
839}
840
841void buildTypeList( const DeclarationNode *firstNode, std::list< Type *> &outputList ) {
842 SemanticError errors;
843 std::back_insert_iterator< std::list< Type *> > out( outputList );
844 const DeclarationNode *cur = firstNode;
845 while ( cur ) {
846 try {
847 *out++ = cur->buildType();
848 } catch( SemanticError &e ) {
849 errors.append( e );
850 } // try
851 cur = dynamic_cast< DeclarationNode *>( cur->get_link() );
852 } // while
853 if ( ! errors.isEmpty() ) {
854 throw errors;
855 } // if
856}
857
858Declaration *DeclarationNode::build() const {
859 if ( type ) {
860 Declaration *newDecl = type->buildDecl( name, buildStorageClass(), maybeBuild< Expression >( bitfieldWidth ), buildFuncSpecifier( Inline ), buildFuncSpecifier( Noreturn ), linkage, maybeBuild< Initializer >(initializer) );
861 return newDecl;
862 } // if
863 if ( ! buildFuncSpecifier( Inline ) && ! buildFuncSpecifier( Noreturn ) ) {
864 return new ObjectDecl( name, buildStorageClass(), linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) );
865 } // if
866 throw SemanticError( "invalid function specifier in declaration of ", this );
867}
868
869Type *DeclarationNode::buildType() const {
870 assert( type );
871
872 switch ( type->kind ) {
873 case TypeData::Enum:
874 return new EnumInstType( type->buildQualifiers(), type->enumeration->name );
875 case TypeData::Aggregate: {
876 ReferenceToType *ret;
877 switch ( type->aggregate->kind ) {
878 case DeclarationNode::Struct:
879 ret = new StructInstType( type->buildQualifiers(), type->aggregate->name );
880 break;
881 case DeclarationNode::Union:
882 ret = new UnionInstType( type->buildQualifiers(), type->aggregate->name );
883 break;
884 case DeclarationNode::Context:
885 ret = new ContextInstType( type->buildQualifiers(), type->aggregate->name );
886 break;
887 default:
888 assert( false );
889 } // switch
890 buildList( type->aggregate->actuals, ret->get_parameters() );
891 return ret;
892 }
893 case TypeData::Symbolic: {
894 TypeInstType *ret = new TypeInstType( type->buildQualifiers(), type->symbolic->name, false );
895 buildList( type->symbolic->actuals, ret->get_parameters() );
896 return ret;
897 }
898 default:
899 return type->build();
900 } // switch
901}
902
903DeclarationNode::StorageClass DeclarationNode::buildStorageClass() const {
904 DeclarationNode::StorageClass ret = DeclarationNode::NoStorageClass;
905 for ( std::list< DeclarationNode::StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
906 if ( *i == DeclarationNode::Inline || *i == DeclarationNode::Noreturn ) continue; // ignore function specifiers
907 if ( ret != DeclarationNode::NoStorageClass ) { // already have a valid storage class ?
908 throw SemanticError( "invalid combination of storage classes in declaration of ", this );
909 } // if
910 ret = *i;
911 } // for
912 return ret;
913}
914
915bool DeclarationNode::buildFuncSpecifier( DeclarationNode::StorageClass key ) const {
916 std::list< DeclarationNode::StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), key );
917 if ( first == storageClasses.end() ) return false; // not found
918 first = std::find( ++first, storageClasses.end(), key ); // found
919 if ( first == storageClasses.end() ) return true; // not found again
920 throw SemanticError( "duplicate function specifier in declaration of ", this );
921}
922
923// Local Variables: //
924// tab-width: 4 //
925// mode: c++ //
926// compile-command: "make install" //
927// End: //
Note: See TracBrowser for help on using the repository browser.