source: src/Parser/DeclarationNode.cc@ ac71a86

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay 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 ac71a86 was ac71a86, checked in by Thierry Delisle <tdelisle@…>, 9 years ago

removed more memory leaks from the system

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