source: src/Parser/DeclarationNode.cc@ 1048b31

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 1048b31 was 45161b4d, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

generate implicit typedef right after sue name appears, further fixes storage allocation routines and comments

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