source: src/Parser/DeclarationNode.cc@ 5b40f30

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 with_gc
Last change on this file since 5b40f30 was 974906e2, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

propagate maybeConstructed flag through system, begin create constructor/destructor statements for further processing by Resolver

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